package tt.dz.service.imp.middleware;

import java.math.BigDecimal;
import java.text.MessageFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

import javax.annotation.Resource;

import org.apache.commons.lang.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import com.alibaba.fastjson.JSON;

import tt.dz.dao.ext.charger.OmsChargerBespeakBillRecordDao;
import tt.dz.dao.ext.charger.OmsChargerChargeBillRecordDao;
import tt.dz.dao.ext.charger.OmsChargerDao;
import tt.dz.dao.ext.charger.OmsChargerOfflineWhitelistDao;
import tt.dz.dao.ext.charger.OmsChargerRateDao;
import tt.dz.dao.ext.charger.OmsChargerStateAlternateDao;
import tt.dz.dao.ext.charger.OmsChargerStateDirectDao;
import tt.dz.dao.ext.common.OmsSplitratioSchemeDao;
import tt.dz.dao.ext.station.OmsStationDao;
import tt.dz.entity.base.JsonCommon;
import tt.dz.entity.base.JsonForList;
import tt.dz.entity.charger.OmsCharger;
import tt.dz.entity.charger.OmsChargerBespeakBillRecord;
import tt.dz.entity.charger.OmsChargerChargeBillRecord;
import tt.dz.entity.charger.OmsChargerErrorRecord;
import tt.dz.entity.charger.OmsChargerOfflineWhitelist;
import tt.dz.entity.charger.OmsChargerStateAlternate;
import tt.dz.entity.charger.OmsChargerStateDirect;
import tt.dz.entity.exception.BizException;
import tt.dz.entity.exception.OmsDaoException;
import tt.dz.entity.station.OmsStation;
import tt.dz.service.charger.OmsChargerErrorRecordService;
import tt.dz.service.imp.middleware.vo.ChargerReplyMsgHeader;
import tt.dz.service.imp.sys.PaymentDetail;
import tt.dz.service.middleware.MessageService;
import tt.dz.service.middleware.OmsBespeakService;
import tt.dz.tcp.rpc.as.SystemAppServerRpcClient;
import tt.dz.tcp.rpc.as.client.constant.AppServerConstant;
import tt.dz.tcp.rpc.as.client.entity.AppOrderNotifyParam;
import tt.dz.tcp.rpc.as.client.entity.AppReservationNotifyParam;
import tt.dz.tcp.rpc.os.OrderRpcClient;
import tt.dz.tcp.socket.exception.CreateConnectionFailException;
import tt.dz.tcp.socket.exception.DuplicateInstructionException;
import tt.dz.tcp.socket.exception.RetryFailException;
import tt.dz.util.CardUtils;
import tt.dz.util.OmsConstant;
import tt.dz.util.OmsConstant.MsgCodeEnum;
import tt.dz.util.OrderConstant;
import tt.dz.util.OrderConstant.BizSystemCode;
import tt.dz.util.OrderConstant.OrderServiceEnum;
import tt.dz.util.RedisClient;
import tt.dz.util.StringUtil;
import tt.dz.util.serialGenerater;
import tt.dz.vo.os.OrderBaseData;
import tt.dz.vo.os.RetVO;
import tt.dz.vo.os.RetVO.OrdersStatus;

@Service
@Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
public class OmsBespeakServiceImpl implements OmsBespeakService {
	private Log log = LogFactory.getLog(OmsBespeakServiceImpl.class);

	public static final int DEFAULT_BESPEAK_MINITUE = 360;

	// @SuppressWarnings("rawtypes")
	// @Autowired
	// BaseDao baseDao;
	@Resource
	OmsChargerDao omsChargerDao;
	@Resource
	OmsChargerStateDirectDao omsChargerStateDirectDao;
	@Resource
	OmsChargerStateAlternateDao omsChargerStateAlternateDao;
	@Resource
	OmsChargerBespeakBillRecordDao omsChargerBespeakBillRecordDao;
	@Resource
	OmsChargerOfflineWhitelistDao omsChargerOfflineWhitelistDao;
	@Resource
	OmsChargerRateDao omsChargerRateDao;
	@Resource(name = "ev3cMessageServiceImpl")
	MessageService ev3cMessageService;
	@Resource(name = "ev3c2MessageServiceImpl")
	MessageService ev3c2MessageService;
	@Resource
	OrderRpcClient orderRpcClient;
	@Resource
	OmsSplitratioSchemeDao omsSplitratioSchemeDao;
	@Resource
	SystemAppServerRpcClient systemAppServerRpcClient;
	@Resource
	OmsChargerErrorRecordService omsChargerErrorRecordService;
	@Resource
	OmsChargerChargeBillRecordDao omsChargerChargeBillRecordDao;
	@Resource
	OmsStationDao omsStationDao;
	
	
	@Resource(name = "ev3c2MessageWrapperImpl")
	MessageWrapper messageWapper;

	@Resource
	PriceService priceService;
	String ev3c_frameCode, ev3c_msgHeader, ev3c_msgBody, protocol_type = "", protocol_version = "";
	JsonCommon<String> json = new JsonCommon<String>();

	private static Lock lock = new ReentrantLock(); // 锁对象

	@Override
	public void bespeakReturn(Map<String, String> map) {
		protocol_type = map.get("protocol_type");
		protocol_version = map.get("protocol_version");
		switch (protocol_type) {
		case "1":
			ev3c_frameCode = "14";
			switch (protocol_version) {
			case "0101":
				ev3c0101BespeakReturn(map);
				break;
			case "0102":
				// 信息头
				ev3c0102BespeakReturn(map);
				// 有信息体
				break;
			// case "0103":
			// // 有信息头，无信息体
			// json = ev3c0103BespeakReturn(map);
			// break;
			default:
				break;
			}
			break;
		default:
			break;
		}
	}

	/**
	 * 针对0101或0102 版本协议 预约回复执行流程如下:
	 * 1.判断回复报文中是否为正常返回,如果响应码不为000000,则做相应处理(记录入故障记录表,再回调);否则进入第二步。
	 * 2.如果响应码为000000,根据实际情况判断是否需要更新直流或交流表信息 3.更新预约记录表(状态为已预约)
	 * 4.根据卡号判断,如果为APP卡号,则调用App
	 * ReservationNotifyParam通知;如果为企业卡号,则调用企业回调URL:参考主服务器login(用户登录使用)接口。
	 * 先查询oms_oper_list中的notifyUrl,如果没有,就不管了。
	 * ps:企业用户登录流程:先访问主服务器,成功后把相应的信息存入oms_oper_list表中。
	 *
	 * 预约记录表:预约状态:1:预约中 2:已预约 3:取消预约中 4:已取消预约 5:充电(流程1:1-2-3-4, 流程2:1-2-5)
	 * 
	 * @param map
	 * @return JsonCommon<String>
	 */
	private void ev3c0101BespeakReturn(Map<String, String> map) {
		log.info("Receive response message from bespeakReturn! curTime = " + new Date().getTime());
		log.info(map);
		JsonCommon<String> json = new JsonCommon<String>();
		String chargerId, responseMsgHeader, responseMsgBody;
		chargerId = map.get("chargerId");
		String data = map.get("data");
		String port = map.get("port"); // 充电口号 BIN码 1 00表示A口,01表示B口 10表示C口···目前还没有C口
		String userCard = map.get("userCard"); // 用户卡号
		String responseCode = data.substring(8, 14); // 获取响应码

		responseMsgBody = "";
		responseMsgHeader = data.substring(0, 2) + "0000" + data.substring(6, 34) + "57" + data.substring(36, 50);
		json.setPojo(responseMsgHeader + responseMsgBody);

		OmsCharger charger_query = new OmsCharger();
		charger_query.setCharger_id(chargerId);
		int port_no = Integer.parseInt(port, 2); // 数据库中是从0开始,报文是从0开始
		charger_query.setPort_no(port_no);
		OmsCharger charger = (OmsCharger) omsChargerDao.findOneExample(charger_query, null, null);
		// 1.判断回复报文中是否为正常返回,如果响应码不为000000,则做相应处理(记录入故障记录表,再回调);否则进入第二步。
		if (checkChargerReplyMessageStatus(responseCode)) { // 正常
			log.info("Receive response message from bespeakReturn(responseCode is normal)");
			// 2.处理预约,更新预约记录表(状态为已预约)
			OmsChargerBespeakBillRecord bespeakBillRecord_query = new OmsChargerBespeakBillRecord();
			bespeakBillRecord_query.setCharger_id(chargerId);
			bespeakBillRecord_query.setUser_pay_card(userCard);
			bespeakBillRecord_query.setPort_no(port_no);
			bespeakBillRecord_query.setStatus(1);
			OmsChargerBespeakBillRecord bespeakBillRecord = omsChargerBespeakBillRecordDao
					.findOneExample(bespeakBillRecord_query, "start_time", "desc");
			bespeakBillRecord.setStatus(2); // 预约状态:1:预约中 2:已预约 3:取消预约中 4:已取消预约 5:充电(流程1:1-2-3-4, 流程2:1-2-5)
			// String oms_msg_bespeak_end_jrnl = serialGenerater.generateSerialNo();
			// bespeakBillRecord.setOms_msg_bespeak_end_jrnl(oms_msg_bespeak_end_jrnl); //
			// 报文结束预约流水号,系统生成,格式为:YYYY-MM-DD-HH-MI-SS加上四位序号,例如:0x20 0x15 0x05 0x
			omsChargerBespeakBillRecordDao.updateObject(bespeakBillRecord); // 更新状态

			int chargerType = 1; // 1:直流 2:交流 3:混合
			OmsChargerStateDirect directState = null; // 直流表信息
			OmsChargerStateAlternate alternateState = null; // 交流表信息
			if (charger.getCharger_type() != null) {
				chargerType = charger.getCharger_type();
				switch (chargerType) { // 1:直流 2:交流 3:混合
				case 1:
					OmsChargerStateDirect directState_query = new OmsChargerStateDirect();
					directState_query.setPort_no(port_no);
					directState_query.setCharger_id(map.get("chargerId"));
					directState = (OmsChargerStateDirect) omsChargerStateDirectDao.findOneExample(directState_query,
							null, null);

					directState.setCharge_status(1); // 设置电桩状态为(0:空闲,1:预约,2:充电,3:故障,4:占用中(针对双枪单充等情况),5:刷卡中,8:离线)
					directState.setOnline_status(1); // 在线状态(0:代表离线,1:代表在线)
					directState.setBespeak_jrnl(bespeakBillRecord.getOms_msg_bespeak_jrnl()); // 下发报文预约开始流水号(报文开始预约流水号,系统生成,:格式为:YYYY-MM-DD-HH-MI-SS加上四位序号
																								// 例如：0x20 0x15 0x05
																								// 0x10 0x21 0x45
																								// 0x34,0x00,0x00表示2015年5月10日21点击5分34秒第一个流水号(同一时刻自增))
					directState.setUser_pay_card(userCard);
					omsChargerStateDirectDao.updateObject(directState);
					break;
				case 2:
					OmsChargerStateAlternate alternateState_query = new OmsChargerStateAlternate();
					alternateState_query.setPort_no(port_no);
					alternateState_query.setCharger_id(chargerId);
					alternateState = omsChargerStateAlternateDao.findOneExample(alternateState_query, null, null);

					alternateState.setCharge_status(1); // 设置电桩状态为(0:空闲,1:预约,2:充电,3:故障,4:占用中(针对双枪单充等情况),5:刷卡中,8:离线)
					alternateState.setOnline_status(1); // 在线状态(0:代表离线,1:代表在线)
					alternateState.setBespeak_jrnl(bespeakBillRecord.getOms_msg_bespeak_jrnl()); // 下发报文预约开始流水号(报文开始预约流水号,系统生成,:格式为:YYYY-MM-DD-HH-MI-SS加上四位序号
																									// 例如：0x20 0x15 0x05
																									// 0x10 0x21 0x45
																									// 0x34,0x00,0x00表示2015年5月10日21点击5分34秒第一个流水号(同一时刻自增))
					alternateState.setUser_pay_card(userCard);
					omsChargerStateAlternateDao.updateObject(alternateState);
					break;
				default:
					break;
				}
			}

			// 3.根据卡号判断,如果为APP卡号,则调用App ReservationNotifyParam通知;
			// 如果为企业卡号,则调用企业回调URL:参考主服务器login(用户登录使用)接口。
			// 先查询oms_oper_list中的notifyUrl,如果没有,就不管了。
			// 企业用户登录流程:先访问主服务器,成功后把相应的信息存入oms_oper_list表中。
			// 线上卡是18808开头(08 线上卡),线下卡是18806开头(06 现金卡),05 身份认证卡
			try {
				notifyOnReservationSuccess(AppServerConstant.STATION_UPDATE_NOTIFY_ACTION_RESERVATION,
						bespeakBillRecord, charger);
			} catch (BizException e) {
				log.error(e.getMessage(), e);
			}

		} else { // 入库oms_charger_error_record[故障记录表]
			// log.info("Receive response message from
			// bespeakReturn(OmsChargerErrorRecord)");
			// OmsChargerErrorRecord record = new OmsChargerErrorRecord();
			// record.setCharger_id(chargerId);
			// record.setError_code(responseCode);
			// record.setError_msg("BespeakReturn fault!");
			// record.setStatus(0); // 0:未处理,1:已处理
			// record.setValid_flag(1);
			// record.setCreate_oper_id("000");
			// record.setCreate_time(new Date());
			// omsChargerErrorRecordService.add(record);
			//
			// // 报文中需要有直流和交流的区别,如果是为了中新用的,就应该是oms_charger_state_direct[直流充电桩状态表]
			// if (charger.getCharger_type() != null) {
			// int chargerType = charger.getCharger_type();
			// switch (chargerType) { // 1:直流 2:交流 3:混合
			// case 1:
			// OmsChargerStateDirect directState_query = new OmsChargerStateDirect();
			// directState_query.setPort_no(port_no);
			// directState_query.setCharger_id(map.get("chargerId"));
			// OmsChargerStateDirect directState = (OmsChargerStateDirect)
			// omsChargerStateDirectDao.findOneExample(directState_query, null, null);
			// directState.setCharge_status(3); //
			// 设置电桩状态为(0:空闲,1:预约,2:充电,3:故障,4:占用中(针对双枪单充等情况),5:刷卡中,8:离线)
			// directState.setOnline_status(1); // 在线状态(0:代表离线,1:代表在线)
			// directState.setBespeak_jrnl(""); //
			// 下发报文预约开始流水号(报文开始预约流水号,系统生成,:格式为:YYYY-MM-DD-HH-MI-SS加上四位序号 例如：0x20 0x15 0x05
			// 0x10 0x21 0x45 0x34,0x00,0x00表示2015年5月10日21点击5分34秒第一个流水号(同一时刻自增))
			// omsChargerStateDirectDao.updateObject(directState);
			// break;
			// case 2:
			// OmsChargerStateAlternate alternateState_query = new
			// OmsChargerStateAlternate();
			// alternateState_query.setPort_no(port_no);
			// alternateState_query.setCharger_id(chargerId);
			// OmsChargerStateAlternate alternateState =
			// omsChargerStateAlternateDao.findOneExample(alternateState_query, null, null);
			// alternateState.setCharge_status(3); //
			// 设置电桩状态为(0:空闲,1:预约,2:充电,3:故障,4:占用中(针对双枪单充等情况),5:刷卡中,8:离线)
			// alternateState.setOnline_status(1); // 在线状态(0:代表离线,1:代表在线)
			// alternateState.setBespeak_jrnl(""); //
			// 下发报文预约开始流水号(报文开始预约流水号,系统生成,:格式为:YYYY-MM-DD-HH-MI-SS加上四位序号 例如：0x20 0x15 0x05
			// 0x10 0x21 0x45 0x34,0x00,0x00表示2015年5月10日21点击5分34秒第一个流水号(同一时刻自增))
			// omsChargerStateAlternateDao.updateObject(alternateState);
			// break;
			// default:
			// break;
			// }
			// }
			//
			// json.setCode(OmsConstant.ErrorCodeEnum.ConnectionResultChargerException.value());
			// json.setMsg("chargerId " + chargerId + "userCard " + userCard + "
			// ev3c0101BespeakReturn: bespeakReturn connection status fail!"); // 带卡号
			// log.error("chargerId " + chargerId + " Class:OmsBespeakServiceImpl ->
			// method:ev3c0101BespeakReturn -> result:bespeakReturn connection status
			// fail!");
		}
	}

	private void ev3c0102BespeakReturn(Map<String, String> map) {
		ev3c0101BespeakReturn(map);
	}

	private JsonCommon<String> ev3c0103BespeakReturn(Map<String, String> map) {
		JsonCommon<String> json = new JsonCommon<String>();
		String chargerId, requestURL, responseMsgHeader, responseMsgBody;
		// String[] header = StringUtil.getMessageHeader(data);
		// Map<String,String> headMap = StringUtil.getParameter(request);
		chargerId = map.get("chargerId");
		String data = map.get("data");
		String port = map.get("port"); // 充电口号 BIN码 1 00表示A口，01表示B口
										// 10表示C口···目前还没有C口
		String userCard = map.get("userCard"); // 用户卡号
		String startTime = map.get("startTime"); // 预约开始时间 BCD码 7
													// 格式YYYY-MM-DD-hh-mm-ss
													// 例如：0x20 0x15 0x05 0x10
													// 0x13 0x20
													// 0x11,表示2015年5月10日13时20分11秒
		Date startTime_date = StringUtil.StrToDate(startTime);
		// 之前是char_bespeak_record，现在这个表已经被合并到char_bespeak_bill_record[预约费用记录表]中了。
		OmsChargerBespeakBillRecord billRecord = new OmsChargerBespeakBillRecord();
		OmsCharger charger_query = new OmsCharger();
		charger_query.setCharger_id(chargerId);
		int port_no = Integer.parseInt(port, 2);// 数据库中是从0开始，报文是从0开始
		// charger_query.setPort_no(port_no);
		OmsCharger charger = (OmsCharger) omsChargerDao.findOneExample(charger_query, null, null);

		// String key = chargerId+port_no+userCard;
		String key = chargerId + port + userCard + "_bespeakMinute";
		String bespeakMinute = RedisClient.get(key);
		if (StringUtil.isNotBlank(bespeakMinute)) {
			int bespeakMinute_int = Integer.valueOf(bespeakMinute);
			// startTime_date.
			Calendar ca = Calendar.getInstance();
			ca.setTime(startTime_date);
			ca.add(Calendar.MINUTE, bespeakMinute_int);
			Date estimate_end_time = ca.getTime();
			// Date estimate_end_time = startTime_date + bespeakMinute_int;
			billRecord.setEstimate_end_time(estimate_end_time);
			RedisClient.delByKey(key);
		}
		billRecord.setCharger_id(map.get("chargerId").toString());
		billRecord.setPort_no(port_no);
		billRecord.setUser_pay_card(userCard);
		billRecord.setStation_id(charger.getStation_id());
		billRecord.setValid_flag(1);
		billRecord.setStart_time(startTime_date);// 1.3独有
		billRecord.setIs_done(0);
		billRecord.setEstimate_end_time(null);// 预约理论结束时间
		billRecord.setBespeak_deal_charge(null);// 最终预约结算费用
		billRecord.setBespeak_jrnl(
				userCard + "0" + port_no + StringUtil.now14time() + serialGenerater.generateSerialNo());
		omsChargerBespeakBillRecordDao.save(billRecord);
		// 更新状态 oms_charger_state_alternate[交流充电桩状态表]
		// oms_charger_state_direct[直流充电桩状态表]
		// 报文中需要有直流和交流的区别，如果是为了中新用的，就应该是oms_charger_state_direct[直流充电桩状态表]
		if (charger.getCharger_type() != null) {
			int chargerType = charger.getCharger_type();
			switch (chargerType) {// 1--直流 2--交流 3--混合
			case 1:
				OmsChargerStateDirect directState_query = new OmsChargerStateDirect();
				directState_query.setPort_no(port_no);
				directState_query.setCharger_id(map.get("chargerId"));
				OmsChargerStateDirect directState = (OmsChargerStateDirect) omsChargerStateDirectDao
						.findOneExample(directState_query, null, null);
				directState.setCharge_status(1);
				directState.setOnline_status(1);
				omsChargerStateDirectDao.updateObject(directState);
				break;
			case 2:
				OmsChargerStateAlternate alternateState_query = new OmsChargerStateAlternate();
				alternateState_query.setPort_no(port_no);
				alternateState_query.setCharger_id(chargerId);
				OmsChargerStateAlternate alternateState = omsChargerStateAlternateDao
						.findOneExample(alternateState_query, null, null);
				alternateState.setCharge_status(1);
				alternateState.setOnline_status(1);
				omsChargerStateAlternateDao.updateObject(alternateState);
				break;
			default:
				break;
			}
		}
		json.setCode("200");
		json.setMsg("ok");
		// json.setPojo(responseMsgHeader + responseMsgBody);
		return json;
	}

	@Override
	public void cancelBespeakReturn(Map<String, String> map) throws RetryFailException, CreateConnectionFailException {
		protocol_type = map.get("protocol_type");
		protocol_version = map.get("protocol_version");
		String data = map.get("data");
		switch (protocol_type) {
		case "1":
			ev3c_frameCode = "14";
			switch (protocol_version) {
			case "0101":
				ev3c0101CancelBespeakReturn(map, data);
				break;
			case "0102":
				ev3c0102CancelBespeakReturn(map, data);
				break;
			// case "0103":
			// json = ev3c0103CancelBespeakReturn(map, data);
			// break;
			default:
				break;
			}
			break;
		default:
			break;
		}
	}

	/**
	 * 针对0101或0102 版本协议 取消预约执行流程如下:
	 * 1.判断回复报文中是否为正常返回,如果响应码不为000000,则做相应处理(记录入故障记录表,再回调); 2.生成订单,通知app或第三方App
	 * OrderNotifyParam通知 3.通知app或第三方App ReservationNotifyParam通知
	 *
	 * @param map
	 * @param data
	 * @return
	 */
	// private void ev3c0101CancelBespeakReturn(Map<String, String> map, String
	// data) throws RetryFailException, CreateConnectionFailException
	// {
	// log.info("Receive response message from cancelBespeakReturn! curTime = " +
	// new Date().getTime());
	// ev3c_frameCode = "58";
	// JsonCommon<String> json = new JsonCommon<String>();
	// map.put("portNo", data.substring(50,52)); // 截取枪口号
	// String chargerId, responseMsgHeader, responseMsgBody;
	// chargerId = map.get("chargerId");
	// String port = map.get("port"); // 充电口号 BIN码 1 00表示A口,01表示B口,10表示C口···目前还没有C口
	// String userCard = map.get("userCard"); // 用户卡号
	// String responseCode= data.substring(8, 14); // 获取响应码
	// OmsCharger charger_query = new OmsCharger();
	// charger_query.setCharger_id(chargerId);
	// int port_no = Integer.parseInt(port, 2);// 数据库中是从0开始，报文是从0开始
	// OmsCharger charger = omsChargerDao.findOneExample(charger_query, null, null);
	// responseMsgBody = "";
	// responseMsgHeader = data.substring(0, 2)+"0000"+data.substring(6, 34) + "58"
	// + data.substring(36,50);
	// try {
	// // 1.判断回复报文中是否为正常返回,如果响应码不为000000,则做相应处理(记录入故障记录表,再回调);否则进入第二步。
	// if (checkChargerReplyMessageStatus(responseCode)) { // 正常
	// log.info("Receive response message from cancelbespeakReturn(responseCode is
	// normal)");
	// // 2.生成订单,通知app或第三方App OrderNotifyParam通知
	// OmsChargerBespeakBillRecord omsChargerBespeakBillRecord_query = new
	// OmsChargerBespeakBillRecord();
	// omsChargerBespeakBillRecord_query.setCharger_id(chargerId);
	// omsChargerBespeakBillRecord_query.setPort_no(port_no);
	// omsChargerBespeakBillRecord_query.setUser_pay_card(userCard);
	// OmsChargerBespeakBillRecord omsChargerBespeakBillRecord;
	// //TODO 2:已预约 3:取消预约中 加条件 ，如果没有就不调用订单，直接报文返回
	// omsChargerBespeakBillRecord =
	// omsChargerBespeakBillRecordDao.findOneExampleByCondition(omsChargerBespeakBillRecord_query,
	// " where charger_id = '" + chargerId + "' and port_no = " + port_no + " and
	// user_pay_card = '"+ userCard +"' order by start_time desc ");
	//
	// Date now = new Date();
	// BigDecimal totalAmount =
	// priceService.computeFee(charger.getRate_schema_bespeak_fee(),
	// omsChargerBespeakBillRecord.getStart_time(), now);
	// omsChargerBespeakBillRecord.setBespeak_deal_before(Float.valueOf(totalAmount.toString()));
	// omsChargerBespeakBillRecord.setActual_end_time(now);
	// RetVO.CreatedOrderVO retVO =
	// createOrderWhenCancelReservation(omsChargerBespeakBillRecord, charger);
	// // json = sendOrderToAppServer(map, 2);
	// // 3.通知app或第三方App ReservationNotifyParam通知
	// omsChargerBespeakBillRecord.setStatus(4); // 预约状态:1:预约中 2:已预约 3:取消预约中 4:已取消预约
	// 5:充电(流程1:1-2-3-4, 流程2:1-2-5)
	// omsChargerBespeakBillRecord.setOrder_no(retVO.getOrderNo());
	// omsChargerBespeakBillRecord.setBespeak_deal_charge(Float.valueOf(retVO.getTotalFee().toString()));
	// omsChargerBespeakBillRecordDao.updateObject(omsChargerBespeakBillRecord); //
	// 更新状态
	//
	// // 4.处理取消预约后,改变桩对应枪口的状态
	// // 报文中需要有直流和交流的区别,如果是为了中新用的,就应该是oms_charger_state_direct[直流充电桩状态表]
	// if (charger.getCharger_type() != null) {
	// int chargerType = charger.getCharger_type();
	// switch (chargerType) { // 1:直流 2:交流 3:混合
	// case 1:
	// OmsChargerStateDirect directState_query = new OmsChargerStateDirect();
	// directState_query.setPort_no(port_no);
	// directState_query.setCharger_id(map.get("chargerId"));
	// OmsChargerStateDirect directState = (OmsChargerStateDirect)
	// omsChargerStateDirectDao.findOneExample(directState_query, null, null);
	// directState.setCharge_status(0); // 设置为空闲
	// omsChargerStateDirectDao.updateObject(directState);
	// break;
	// case 2:
	// OmsChargerStateAlternate alternateState_query = new
	// OmsChargerStateAlternate();
	// alternateState_query.setPort_no(port_no);
	// alternateState_query.setCharger_id(chargerId);
	// OmsChargerStateAlternate alternateState =
	// omsChargerStateAlternateDao.findOneExample(alternateState_query, null, null);
	// alternateState.setCharge_status(0); // 设置为空闲
	// omsChargerStateAlternateDao.updateObject(alternateState);
	// break;
	// default:
	// break;
	// }
	// }
	//
	// // 5.通知:取消预约通知接口
	// log.info("Receive response message from
	// cancelBespeakReturn(AppReservationNotifyParam)");
	// try {
	// notifyOnReservationSuccess(AppServerConstant.STATION_UPDATE_NOTIFY_ACTION_CANCEL_RESERVATION,
	// omsChargerBespeakBillRecord, charger);
	// notifyOnReservationFee(retVO, omsChargerBespeakBillRecord);
	// } catch (BizException e) {
	// log.error(e.getMessage(), e);
	// json.setPojo(responseMsgHeader + responseMsgBody);
	// json.setCode("400");
	// throw e;
	// }
	//
	// // 4.发送报文
	// try {
	// ev3cMessageService.sendNoWait(responseMsgHeader+responseMsgBody, chargerId);
	//
	// log.debug("chargerId "+ chargerId +" cancelBespeakReturn reservationNotify
	// success, cancelBespeakReturn sendNoWait success!");
	// json.setPojo(responseMsgHeader + responseMsgBody);
	// json.setCode("200");
	// } catch (CreateConnectionFailException | RetryFailException e) {
	// log.error(e.getMessage(), e);
	// json.setPojo(responseMsgHeader + responseMsgBody);
	// json.setCode("400");
	// throw e;
	// }
	// } else { // 入库oms_charger_error_record[故障记录表]
	//// OmsChargerErrorRecord record = new OmsChargerErrorRecord();
	//// record.setCharger_id(chargerId);
	//// record.setError_code(responseCode);
	//// record.setError_msg("CancelBespeakReturn fault!");
	//// record.setStatus(0); // 0:未处理,1:已处理
	//// record.setValid_flag(1);
	//// record.setCreate_oper_id("000");
	//// record.setCreate_time(new Date());
	//// omsChargerErrorRecordService.add(record);
	////
	//// // 报文中需要有直流和交流的区别,如果是为了中新用的,就应该是oms_charger_state_direct[直流充电桩状态表]
	//// if (charger.getCharger_type() != null) {
	//// int chargerType = charger.getCharger_type();
	//// switch (chargerType) { // 1:直流 2:交流 3:混合
	//// case 1:
	//// OmsChargerStateDirect directState_query = new OmsChargerStateDirect();
	//// directState_query.setPort_no(port_no);
	//// directState_query.setCharger_id(map.get("chargerId"));
	//// OmsChargerStateDirect directState = (OmsChargerStateDirect)
	// omsChargerStateDirectDao.findOneExample(directState_query, null, null);
	//// directState.setCharge_status(3); //
	// 设置电桩状态为(0:空闲,1:预约,2:充电,3:故障,4:占用中(针对双枪单充等情况),5:刷卡中,8:离线)
	//// directState.setOnline_status(1); // 在线状态(0:代表离线,1:代表在线)
	//// omsChargerStateDirectDao.updateObject(directState);
	//// break;
	//// case 2:
	//// OmsChargerStateAlternate alternateState_query = new
	// OmsChargerStateAlternate();
	//// alternateState_query.setPort_no(port_no);
	//// alternateState_query.setCharger_id(chargerId);
	//// OmsChargerStateAlternate alternateState =
	// omsChargerStateAlternateDao.findOneExample(alternateState_query, null, null);
	//// alternateState.setCharge_status(3); //
	// 设置电桩状态为(0:空闲,1:预约,2:充电,3:故障,4:占用中(针对双枪单充等情况),5:刷卡中,8:离线)
	//// alternateState.setOnline_status(1); // 在线状态(0:代表离线,1:代表在线)
	//// omsChargerStateAlternateDao.updateObject(alternateState);
	//// break;
	//// default:
	//// break;
	//// }
	//// }
	// }
	// } catch (Exception e) {
	// log.error(e.getMessage(), e);
	// json.setPojo(responseMsgHeader + responseMsgBody);
	// json.setCode("400");
	// }
	// }

	/**
	 * pengyu 20160923 modify for test 针对0101或0102 版本协议 取消预约执行流程如下:
	 * 1.判断回复报文中是否为正常返回,如果响应码不为000000,则做相应处理(记录入故障记录表,再回调); 2.生成订单,通知app或第三方App
	 * OrderNotifyParam通知 3.通知app或第三方App ReservationNotifyParam通知
	 *
	 * @param map
	 * @param data
	 * @return
	 */
	private void ev3c0101CancelBespeakReturn(Map<String, String> map, String data)
			throws RetryFailException, CreateConnectionFailException {
		log.info("Receive response message from cancelBespeakReturn! curTime = " + new Date().getTime());
		ev3c_frameCode = "58";
		JsonCommon<String> json = new JsonCommon<String>();
		map.put("portNo", data.substring(50, 52)); // 截取枪口号
		String chargerId, responseMsgHeader, responseMsgBody;
		chargerId = map.get("chargerId");
		String port = map.get("port"); // 充电口号 BIN码 1 00表示A口,01表示B口,10表示C口···目前还没有C口
		String userCard = map.get("userCard"); // 用户卡号
		String responseCode = data.substring(8, 14); // 获取响应码
		OmsCharger charger_query = new OmsCharger();
		charger_query.setCharger_id(chargerId);
		int port_no = Integer.parseInt(port, 2);// 数据库中是从0开始，报文是从0开始
		OmsCharger charger = omsChargerDao.findOneExample(charger_query, null, null);
		responseMsgBody = "";
		responseMsgHeader = data.substring(0, 2) + "0000" + data.substring(6, 34) + "58" + data.substring(36, 50);
		try {
			// 1.判断回复报文中是否为正常返回,如果响应码不为000000,则做相应处理(记录入故障记录表,再回调);否则进入第二步。
			if (checkChargerReplyMessageStatus(responseCode)) { // 正常
				log.info("Receive response message from cancelbespeakReturn(responseCode is normal)");
				// 2.生成订单,通知app或第三方App OrderNotifyParam通知
				OmsChargerBespeakBillRecord omsChargerBespeakBillRecord_query = new OmsChargerBespeakBillRecord();
				omsChargerBespeakBillRecord_query.setCharger_id(chargerId);
				omsChargerBespeakBillRecord_query.setPort_no(port_no);
				omsChargerBespeakBillRecord_query.setUser_pay_card(userCard);
				OmsChargerBespeakBillRecord omsChargerBespeakBillRecord;
				// TODO 2:已预约 3:取消预约中 加条件 ，如果没有就不调用订单，直接报文返回
				omsChargerBespeakBillRecord = omsChargerBespeakBillRecordDao
						.findOneExampleByCondition(omsChargerBespeakBillRecord_query,
								" where charger_id = '" + chargerId + "' and port_no = " + port_no
										+ " and user_pay_card = '" + userCard
										+ "' and status in (2,3)  order by start_time desc ");

				if (omsChargerBespeakBillRecord == null) {
					// 4.发送报文
					try {
						responseMsgHeader = data.substring(0, 2) + "000001" + "FF0201" + data.substring(14, 34) + "58"
								+ data.substring(36, 50);
						ev3cMessageService.sendNoWait(responseMsgHeader + responseMsgBody, chargerId);

						log.debug("chargerId " + chargerId
								+ " cancelBespeakReturn reservationNotify success, cancelBespeakReturn sendNoWait success!");
						json.setPojo(responseMsgHeader + responseMsgBody);
						json.setCode("200");
						return;
					} catch (CreateConnectionFailException | RetryFailException e) {
						log.error(e.getMessage(), e);
						json.setPojo(responseMsgHeader + responseMsgBody);
						json.setCode("400");
						throw e;
					}
				}
				Date now = new Date();
				List<PaymentDetail> reservationFeeDetails = new ArrayList<>();
				BigDecimal totalAmount = priceService.computeFee(charger.getRate_schema_bespeak_fee(),
						omsChargerBespeakBillRecord.getStart_time(), now, reservationFeeDetails);
				omsChargerBespeakBillRecord.setBespeak_deal_before(Float.valueOf(totalAmount.toString()));
				omsChargerBespeakBillRecord.setActual_end_time(now);
				RetVO.CreatedOrderVO retVO = createOrderWhenCancelReservation(omsChargerBespeakBillRecord, charger,
						reservationFeeDetails);
				// json = sendOrderToAppServer(map, 2);
				// 3.通知app或第三方App ReservationNotifyParam通知
				omsChargerBespeakBillRecord.setStatus(4); // 预约状态:1:预约中 2:已预约 3:取消预约中 4:已取消预约 5:充电(流程1:1-2-3-4,
															// 流程2:1-2-5)
				omsChargerBespeakBillRecord.setOrder_no(retVO.getOrderNo());
				omsChargerBespeakBillRecord.setBespeak_deal_charge(Float.valueOf(retVO.getTotalFee().toString()));
				omsChargerBespeakBillRecordDao.updateObject(omsChargerBespeakBillRecord); // 更新状态

				// 4.处理取消预约后,改变桩对应枪口的状态
				// 报文中需要有直流和交流的区别,如果是为了中新用的,就应该是oms_charger_state_direct[直流充电桩状态表]
				if (charger.getCharger_type() != null) {
					int chargerType = charger.getCharger_type();
					switch (chargerType) { // 1:直流 2:交流 3:混合
					case 1:
						OmsChargerStateDirect directState_query = new OmsChargerStateDirect();
						directState_query.setPort_no(port_no);
						directState_query.setCharger_id(map.get("chargerId"));
						OmsChargerStateDirect directState = (OmsChargerStateDirect) omsChargerStateDirectDao
								.findOneExample(directState_query, null, null);
						directState.setCharge_status(0); // 设置为空闲
						omsChargerStateDirectDao.updateObject(directState);
						break;
					case 2:
						OmsChargerStateAlternate alternateState_query = new OmsChargerStateAlternate();
						alternateState_query.setPort_no(port_no);
						alternateState_query.setCharger_id(chargerId);
						OmsChargerStateAlternate alternateState = omsChargerStateAlternateDao
								.findOneExample(alternateState_query, null, null);
						alternateState.setCharge_status(0); // 设置为空闲
						omsChargerStateAlternateDao.updateObject(alternateState);
						break;
					default:
						break;
					}
				}

				// 5.通知:取消预约通知接口
				log.info("Receive response message from cancelBespeakReturn(AppReservationNotifyParam)");
				try {
					notifyOnReservationSuccess(AppServerConstant.STATION_UPDATE_NOTIFY_ACTION_CANCEL_RESERVATION,
							omsChargerBespeakBillRecord, charger);
					notifyOnReservationFee(retVO, omsChargerBespeakBillRecord);
				} catch (BizException e) {
					log.error(e.getMessage(), e);
					json.setPojo(responseMsgHeader + responseMsgBody);
					json.setCode("400");
					throw e;
				}

				// 4.发送报文
				try {
					ev3cMessageService.sendNoWait(responseMsgHeader + responseMsgBody, chargerId);

					log.debug("chargerId " + chargerId
							+ " cancelBespeakReturn reservationNotify success, cancelBespeakReturn sendNoWait success!");
					json.setPojo(responseMsgHeader + responseMsgBody);
					json.setCode("200");
				} catch (CreateConnectionFailException | RetryFailException e) {
					log.error(e.getMessage(), e);
					json.setPojo(responseMsgHeader + responseMsgBody);
					json.setCode("400");
					throw e;
				}
			} else { // 入库oms_charger_error_record[故障记录表]
				// OmsChargerErrorRecord record = new OmsChargerErrorRecord();
				// record.setCharger_id(chargerId);
				// record.setError_code(responseCode);
				// record.setError_msg("CancelBespeakReturn fault!");
				// record.setStatus(0); // 0:未处理,1:已处理
				// record.setValid_flag(1);
				// record.setCreate_oper_id("000");
				// record.setCreate_time(new Date());
				// omsChargerErrorRecordService.add(record);
				//
				// // 报文中需要有直流和交流的区别,如果是为了中新用的,就应该是oms_charger_state_direct[直流充电桩状态表]
				// if (charger.getCharger_type() != null) {
				// int chargerType = charger.getCharger_type();
				// switch (chargerType) { // 1:直流 2:交流 3:混合
				// case 1:
				// OmsChargerStateDirect directState_query = new OmsChargerStateDirect();
				// directState_query.setPort_no(port_no);
				// directState_query.setCharger_id(map.get("chargerId"));
				// OmsChargerStateDirect directState = (OmsChargerStateDirect)
				// omsChargerStateDirectDao.findOneExample(directState_query, null, null);
				// directState.setCharge_status(3); //
				// 设置电桩状态为(0:空闲,1:预约,2:充电,3:故障,4:占用中(针对双枪单充等情况),5:刷卡中,8:离线)
				// directState.setOnline_status(1); // 在线状态(0:代表离线,1:代表在线)
				// omsChargerStateDirectDao.updateObject(directState);
				// break;
				// case 2:
				// OmsChargerStateAlternate alternateState_query = new
				// OmsChargerStateAlternate();
				// alternateState_query.setPort_no(port_no);
				// alternateState_query.setCharger_id(chargerId);
				// OmsChargerStateAlternate alternateState =
				// omsChargerStateAlternateDao.findOneExample(alternateState_query, null, null);
				// alternateState.setCharge_status(3); //
				// 设置电桩状态为(0:空闲,1:预约,2:充电,3:故障,4:占用中(针对双枪单充等情况),5:刷卡中,8:离线)
				// alternateState.setOnline_status(1); // 在线状态(0:代表离线,1:代表在线)
				// omsChargerStateAlternateDao.updateObject(alternateState);
				// break;
				// default:
				// break;
				// }
				// }
			}
		} catch (Exception e) {
			log.error(e.getMessage(), e);
			json.setPojo(responseMsgHeader + responseMsgBody);
			json.setCode("400");
		}
	}

	private void ev3c0102CancelBespeakReturn(Map<String, String> map, String data)
			throws RetryFailException, CreateConnectionFailException {
		ev3c0101CancelBespeakReturn(map, data);
	}

	private JsonCommon<String> ev3c0103CancelBespeakReturn(Map<String, String> map, String data) {
		// String endTime = data.substring(86, 100); // 预约结束时间 BCD码 7
		// // 格式YYYY-MM-DD-hh-mm-ss
		// // 例如：0x20 0x15 0x05 0x10
		// // 0x13 0x20
		// // 0x11,表示2015年5月10日13时20分11秒
		// Date endTime_date = StringUtil.StrToDate(endTime);
		JsonCommon<String> json = new JsonCommon<String>();
		String chargerId, requestURL, responseMsgHeader, responseMsgBody;
		// String[] header = StringUtil.getMessageHeader(data);
		// Map<String,String> headMap = StringUtil.getParameter(request);
		chargerId = map.get("chargerId");
		// String userCard = "0";
		String port = map.get("port"); // 充电口号 BIN码 1 00表示A口，01表示B口
										// 10表示C口···目前还没有C口
		String userCard = map.get("userCard"); // 用户卡号
		String startTime = map.get("startTime"); // 预约开始时间 BCD码 7 1.3独有
		Date startTime_date = StringUtil.StrToDate(startTime);
		String endTime = map.get("endTime"); //
		Date endTime_date = StringUtil.StrToDate(endTime);
		OmsCharger charger_query = new OmsCharger();
		charger_query.setCharger_id(chargerId);
		int port_no = Integer.parseInt(port, 2);// 数据库中是从0开始，报文是从0开始
		// charger_query.setPort_no(port_no);
		OmsCharger charger = omsChargerDao.findOneExample(charger_query, null, null);
		if (charger == null || charger.getCharger_type() == null) {
			json.setCode("400");
			json.setMsg("no charger found");
			responseMsgHeader = data.substring(0, 8) + OmsConstant.MsgResponseCodeEnum.SysError.value()
					+ data.substring(14, 34) + ev3c_frameCode + data.substring(36, 50);
			json.setPojo(responseMsgHeader);
			log.error("chargerId " + chargerId
					+ " Class:OmsBespeakServiceImpl -> method:ev3c0103CancelBespeakReturn -> result:no charger found!");
			return json;
		}

		// omsChargerBespeakBillRecordDao.updateObject();
		int chargerType = charger.getCharger_type();
		switch (chargerType) {// 1--直流 2--交流 3--混合
		case 1:
			OmsChargerStateDirect directState_query = new OmsChargerStateDirect();
			directState_query.setPort_no(port_no);
			directState_query.setCharger_id(chargerId);
			OmsChargerStateDirect directState = omsChargerStateDirectDao.findOneExample(directState_query, null, null);
			directState.setCharge_status(0);
			directState.setOnline_status(1);
			omsChargerStateDirectDao.updateObject(directState);
			break;
		case 2:
			OmsChargerStateAlternate alternateState_query = new OmsChargerStateAlternate();
			alternateState_query.setPort_no(port_no);
			alternateState_query.setCharger_id(chargerId);
			OmsChargerStateAlternate alternateState = omsChargerStateAlternateDao.findOneExample(alternateState_query,
					null, null);
			alternateState.setCharge_status(0);
			alternateState.setOnline_status(1);
			omsChargerStateAlternateDao.updateObject(alternateState);
			break;
		default:
			break;
		}
		OmsChargerBespeakBillRecord omsChargerBespeakBillRecord_query = new OmsChargerBespeakBillRecord();
		omsChargerBespeakBillRecord_query.setCharger_id(chargerId);
		omsChargerBespeakBillRecord_query.setPort_no(port_no);
		omsChargerBespeakBillRecord_query.setUser_pay_card(userCard);
		omsChargerBespeakBillRecord_query.setStart_time(startTime_date);
		Date now = new Date();
		// omsChargerBespeakBillRecord.setStart_time(start_time);//ev3c 1.1 1.2
		// 是没有预约时间和实际预约结束时间 返回的
		OmsChargerBespeakBillRecord omsChargerBespeakBillRecord = omsChargerBespeakBillRecordDao
				.findOneExampleByCondition(omsChargerBespeakBillRecord_query, " order by start_time desc ");
		boolean flag = true;
		if (omsChargerBespeakBillRecord == null) {
			flag = false;
			omsChargerBespeakBillRecord = new OmsChargerBespeakBillRecord();
			omsChargerBespeakBillRecord.setValid_flag(1);
			omsChargerBespeakBillRecord.setBespeak_jrnl(userCard + "0" + port_no + StringUtil.now14time());
		}
		// 调用OS接口生成订单，更新bespeak_deal_charge 最终预约结算费用
		List<OrderBaseData> orderBaseDatas = new ArrayList<OrderBaseData>();
		OrderBaseData orderBaseData = new OrderBaseData();
		if (userCard.startsWith("18808") && !userCard.substring(0, 9).equals("188089999")) {// TODO
																							// 等第三方企业确定了，需要增加BizSystemCode的子集
			orderBaseData.setAppId(BizSystemCode.DzApp.value());
		}
		Long min = StringUtil.dateMinusMinLong(now, omsChargerBespeakBillRecord.getStart_time());
		orderBaseData.setBuyNum(new BigDecimal(min));
		orderBaseData.setCardNo(userCard);
		orderBaseData.setCardType(map.get("cardType"));
		orderBaseData.setEndTime(endTime_date);
		orderBaseData.setEquipmentNo(chargerId);
		orderBaseData.setPlantId(charger.getStation_id());
		orderBaseData.setServiceNo(OrderServiceEnum.Reservation.value());
		orderBaseData.setServiceProviderCode(charger.getOper_merchant_id());
		// TODO 查询预约费率号，再根据时间来确定
		BigDecimal a1 = new BigDecimal(0.8);
		BigDecimal a2 = new BigDecimal(15);
		orderBaseData.setUnitPrice(a1.divide(a2, 0, BigDecimal.ROUND_HALF_EVEN));
		orderBaseData.setAuxEquipmentNo("0");
		// 查询卡号是不是在白名单里面。
		OmsChargerOfflineWhitelist whitelist_query = new OmsChargerOfflineWhitelist();
		whitelist_query.setCharger_id(chargerId);
		whitelist_query.setUser_pay_card(userCard);
		OmsChargerOfflineWhitelist whitelist = omsChargerOfflineWhitelistDao.findOneExample(whitelist_query, null,
				null);
		if (whitelist != null) {
			orderBaseData.setTotalPrice(new BigDecimal(0));
		}
		orderBaseDatas.add(orderBaseData);
		// TODO 测试时屏蔽，正式时打开
		// RetVO retVO = orderRpcClient.createOrder(orderBaseDatas);
		// if(retVO==null||!retVO.getRetCode().equals(retVO.SuccessCode)){
		// json.setCode(retVO.FailCode);
		// json.setMsg("createOrder fail");
		// responseMsgHeader =data.substring(0, 34)+"55"+data.substring(36);
		// json.setPojo(responseMsgHeader);
		// return json;
		// }
		// String bizData = (String) retVO.getBizData();
		// CreatedOrderVO createdOrderVO = JSON.parseObject(bizData,
		// CreatedOrderVO.class);
		// omsChargerChargeBillRecord.setThis_amount(Float.valueOf(createdOrderVO.getTotalFee().toString()));
		// 更新预约费用表中预约结束时间
		omsChargerBespeakBillRecord.setActual_end_time(now);
		if (whitelist != null) {
			omsChargerBespeakBillRecord.setBespeak_deal_charge(0f);
		} else {
			// TODO 订单中的费用
			omsChargerBespeakBillRecord.setBespeak_deal_charge(0f);
		}
		if (flag == true) {
			omsChargerBespeakBillRecordDao.updateObject(omsChargerBespeakBillRecord);
		} else {
			omsChargerBespeakBillRecordDao.save(omsChargerBespeakBillRecord);
		}
		// api_v3.php中的1458行 HttpGetRequest 是调用AS的接口 dzAppURL
		responseMsgBody = "";
		responseMsgHeader = data.substring(0, 2) + "0000" + data.substring(6, 34) + "58" + data.substring(36, 50);
		// StringUtil.sendSocket(responseMsgHeader);
		try {
			ev3cMessageService.sendNoWait(ev3c_msgHeader + ev3c_msgBody, chargerId);
		} catch (RetryFailException e) {
			e.printStackTrace();
			json.setCode("400");
			json.setMsg("chargerId " + chargerId + " cancelBespeakReturn sendSocket fail " + e.getMessage());
			log.error("chargerId " + chargerId
					+ " Class:OmsBespeakServiceImpl -> method:ev3c0103CancelBespeakReturn -> result:cancelBespeakReturn sendNoWait fail! "
					+ e.getMessage());
			return json;
		} catch (CreateConnectionFailException e) {
			e.printStackTrace();
			json.setCode("400");
			json.setMsg("chargerId " + chargerId + " cancelBespeakReturn sendSocket fail " + e.getMessage());
			log.error("chargerId " + chargerId
					+ " Class:OmsBespeakServiceImpl -> method:ev3c0103CancelBespeakReturn -> result:cancelBespeakReturn sendNoWait fail! "
					+ e.getMessage());
			return json;
		} catch (DuplicateInstructionException e) {
			log.error("Send message failure, repeat instruction! e = " + e.getMessage(), e);
			json.setMsg("chargerId " + chargerId + " cancelBespeakReturn sendSocket fail " + e.getMessage());
			log.error("chargerId " + chargerId
					+ " Class:OmsBespeakServiceImpl -> method:ev3c0103CancelBespeakReturn -> result:cancelBespeakReturn sendNoWait fail! "
					+ e.getMessage());
			return json;
		}
		// TODO 根据用户卡号，判断是调用AS接口还是第三方企业接口
		// String dzFun = "&a=beseakcancle";
		// requestURL = StringUtil.dzAppURL + dzFun + "&dianzhuanghao=" +
		// charger.getQr_code() + "&user_pay_card="
		// + userCard + "&bespeak_time=" + StringUtil.now14time() + "&dianzhanid=" +
		// charger.getStation_id();
		// StringUtil.httpGetRequest(requestURL);
		json.setCode("200");
		json.setMsg("ok");
		json.setPojo(responseMsgHeader + responseMsgBody);
		return json;
	}

	@Override
	public JsonCommon<String> bespeak(Map<String, String> map) throws Exception {
		protocol_type = map.get("protocol_type");
		protocol_version = map.get("protocol_version");
		String data = map.get("data");
		switch (protocol_type) {
		case "1":
			ev3c_frameCode = "14";
			switch (protocol_version) {
			case "0101":
				json = ev3c0101Bespeak(map, data);
				break;
			case "0102":
				// 信息头
				json = ev3c0102Bespeak(map, data);
				// 有信息体
				break;
			// case "0103":
			// // 有信息头，无信息体
			// json = ev3c0103Bespeak(map, data);
			// break;
			case "0201":
				json = ev3c0201Bespeak(map);
				break;
			default:
				break;
			}
			break;
		default:
			break;
		}
		return json;
	}

	/**
	 * 针对0101或0102 版本协议 预约执行流程如下: 1.判断该枪口状态,若为空闲状态可预约成功,进入第二步;否则:接口直接返回预约失败信息
	 * 2.生成预约流水号和状态为预约已下发,入库预约记录表,并更新直流或交流表信息(使用锁,保证数据一致性) 3.下发报文
	 *
	 * 预约记录表,预约状态:1:预约中 2:已预约 3:取消预约中 4:已取消预约 5:充电(流程1:1-2-3-4, 流程2:1-2-5)
	 *
	 * 特别地:预约开始时,查询预约费用表和充电费用表:如果有未支付订单(存在订单号而且未支付),则不允许预约;
	 * 如果有,则调用订单服务器接口把未支付订单号列表提供给OS,查询后确认这些是否已支付:如果已支付,就回写数据库相关记录,并允许预约
	 *
	 * @param map
	 * @param data
	 * @return JsonCommon<String>
	 */
	private JsonCommon<String> ev3c0101Bespeak(Map<String, String> map, String data) {
		log.info("Receive response message from bespeak! curTime = " + new Date().getTime());
		String chargerId, portNo, userCard;
		chargerId = map.get("chargerId");
		portNo = map.get("portNo");
		portNo = Ev3cEncapsulationServiceImpl.portNoWithMsg(portNo);
		userCard = map.get("userCard");
		String serialNo = serialGenerater.generateSerialNo14(); // 序列号
		// 1.组装发下报文
		String ev3c_msgBody = (portNo.length() == 1 ? "0".concat(portNo) : portNo).concat(userCard); // 00表示A口,01表示B口
		String ev3c_msgHeader = "68" + StringUtil.ev3cMsgBodyBin(ev3c_msgBody) + "01" + "000000" + "0001" + chargerId
				+ "14" + serialNo;
		if (StringUtil.isBlank(chargerId) || StringUtil.isBlank(portNo) || StringUtil.isBlank(userCard)) {
			json.setCode(OmsConstant.ErrorCodeEnum.MessageMissParam.value());
			json.setMsg(OmsConstant.ErrorCodeEnum.MessageMissParam.desc());
			log.error("chargerId " + chargerId
					+ " Class:OmsBespeakServiceImpl -> method:ev3c0101Bespeak -> result:Charger id do not exist!");
			return json;
		}
		portNo = Ev3cEncapsulationServiceImpl.portNoWithDb(portNo);

		// 2.判断该枪口状态,若为空闲状态可预约成功(预约采用独占试,考虑到并发,查询枪口状态和入库两个操作必须控制在同一把锁来处理,防止脏数据)
		OmsCharger charger_query = new OmsCharger();
		charger_query.setCharger_id(chargerId);
		int port_no = Integer.parseInt(portNo, 2);
		OmsCharger charger = (OmsCharger) omsChargerDao.findOneExample(charger_query, null, null);
		/** 0:空闲 1:预约 2:充电 3:故障 4:占用中(针对双枪单充等情况) 5:刷卡中 8:离线 */
		int chargeStatus = 0; // 当前桩,对应枪口状态
		int chargerType = 1; // 1:直流 2:交流 3:混合
		OmsChargerStateDirect directState = null; // 直流表信息
		OmsChargerStateAlternate alternateState = null; // 交流表信息

		// 特别地:预约开始时,查询预约费用表和充电费用表:如果有未支付订单(存在订单号而且未支付),则不允许预约;
		// 如果有,则调用订单服务器接口把未支付订单号列表提供给OS,查询后确认这些是否已支付:如果已支付,就回写数据库相关记录,并允许预约
		if (!this.checkBespeakOrderNoPayInfo(userCard)) {
			json.setCode(OmsConstant.ErrorCodeEnum.BespeakResultExistNotPayOrder.value()); // 失败错误码
			json.setMsg("chargerId " + chargerId + " userCard " + userCard + " Exist not pay order!");
			log.error("chargerId " + chargerId + " userCard " + userCard
					+ " Class:OmsBespeakServiceImpl -> method:ev3c0101Bespeak -> result:Exist not pay order!");
			return json;
		}

		if (!this.checkChargerOrderNoPayInfo(userCard)) {
			json.setCode(OmsConstant.ErrorCodeEnum.BespeakResultExistNotPayOrder.value()); // 失败错误码
			json.setMsg("chargerId " + chargerId + " userCard " + userCard + " Exist not pay order!");
			log.error("chargerId " + chargerId + " userCard " + userCard
					+ " Class:OmsBespeakServiceImpl -> method:ev3c0101Bespeak -> result:Exist not pay order!");
			return json;
		}

		try {
			lock.lock(); // 得到锁
			// 2.1查询枪口当前状态
			if (charger.getCharger_type() != null) {
				chargerType = charger.getCharger_type();
				switch (chargerType) { // 1:直流 2:交流 3:混合
				case 1:
					OmsChargerStateDirect directState_query = new OmsChargerStateDirect();
					directState_query.setPort_no(port_no);
					directState_query.setCharger_id(map.get("chargerId"));
					directState = (OmsChargerStateDirect) omsChargerStateDirectDao.findOneExample(directState_query,
							null, null);
					chargeStatus = directState.getCharge_status();
					break;
				case 2:
					OmsChargerStateAlternate alternateState_query = new OmsChargerStateAlternate();
					alternateState_query.setPort_no(port_no);
					alternateState_query.setCharger_id(chargerId);
					alternateState = omsChargerStateAlternateDao.findOneExample(alternateState_query, null, null);
					chargeStatus = alternateState.getCharge_status();
					break;
				default:
					break;
				}

				if (chargeStatus == 0) { // 当前桩,对应枪口状态为空闲
					log.info("Receive response message from bespeak(chargeStatus is free)");
					// 3.1处理预约记录表
					OmsChargerBespeakBillRecord billRecord = new OmsChargerBespeakBillRecord();
					Date now = new Date();
					String bespeak_jrnl = "";
					bespeak_jrnl = chargerId + "0" + port_no + serialGenerater.generateSerialNo(); // 生成流水号 bespeak_jrnl
					billRecord.setBespeak_jrnl(bespeak_jrnl); // 操作流水号:OMS自动根据时间\电桩地址和其他规则生成;此字段用来关联充电费用记录。0000000000为非真实数据。
					String oms_msg_charge_jrnl = serialNo;
					billRecord.setOms_msg_bespeak_jrnl(oms_msg_charge_jrnl); // 报文开始预约流水号,系统生成,格式为:YYYY-MM-DD-HH-MI-SS加上四位序号,例如:0x20
																				// 0x15 0x05 0x
					billRecord.setCharger_id(map.get("chargerId").toString());
					billRecord.setPort_no(port_no); // 枪口号
					billRecord.setUser_pay_card(userCard); // 用户卡号
					billRecord.setStation_id(charger.getStation_id()); // 电站id
					billRecord.setValid_flag(1); // 0:代表已删除,1:代表未删除
					billRecord.setStart_time(now); // 预约开始时间
					billRecord.setIs_done(0); // 是否完成订单(0:未完成 ,1:完成 )
					billRecord.setEstimate_end_time(null); // 预约理论结束时间 或+6个小时
					billRecord.setBespeak_deal_charge(null); // 最终预约结算费用
					billRecord.setStatus(1); // 预约状态:1:预约中 2:已预约 3:取消预约中 4:已取消预约 5:充电(流程1:1-2-3-4, 流程2:1-2-5)
					omsChargerBespeakBillRecordDao.save(billRecord);
				} else { // 否则:接口直接返回预约失败,不下发报文
					json.setCode(OmsConstant.ErrorCodeEnum.BespeakResultChargerBespeaked.value());
					json.setMsg("chargerId " + chargerId + "userCard " + userCard
							+ " ev3c0101Bespeak: The charger has been booking!"); // 带卡号
					log.error("chargerId " + chargerId
							+ " Class:OmsBespeakServiceImpl -> method:ev3c0101Bespeak -> result:The charger has been booking!");
					return json;
				}
			} else { // 桩类型错误
				json.setCode(OmsConstant.ErrorCodeEnum.SystemServiceException.value());
				json.setMsg(
						"chargerId " + chargerId + "userCard " + userCard + " ev3c0101Bespeak: charger typy is error!");
				log.error("chargerId " + chargerId
						+ " Class:OmsBespeakServiceImpl -> method:ev3c0101Bespeak -> result:The charger has been booking!");
				return json;
			}
		} catch (Exception e) {
			json.setCode(OmsConstant.ErrorCodeEnum.SystemServiceException.value());
			json.setMsg("chargerId " + chargerId + "userCard " + userCard
					+ " ev3c0101Bespeak: The charger has been booking! " + e.getMessage()); // 带卡号
			log.error("chargerId " + chargerId
					+ " Class:OmsBespeakServiceImpl -> method:ev3c0101Bespeak -> result:The charger has been booking! "
					+ e.getMessage());
			return json;
		} finally {
			lock.unlock(); // 释放锁
		}

		// 4.下发报文
		try {
			log.info("Send message to bespeak sendNoWait! curTime = " + new Date().getTime());
			ev3cMessageService.sendNoWait(ev3c_msgHeader + ev3c_msgBody, chargerId);

			json.setCode("200"); // 成功返回码
			json.setMsg(chargerId + " bespeak sendSocket success!");
			log.debug("chargerId " + chargerId
					+ " Class:OmsBespeakServiceImpl -> method:ev3c0101Bespeak -> result:bespeak sendSocket success!");
		} catch (RetryFailException e) {
			json.setCode("400"); // 失败错误码
			json.setMsg("chargerId " + chargerId + " bespeak sendSocket fail " + e.getMessage());
			log.error("chargerId " + chargerId
					+ " Class:OmsBespeakServiceImpl -> method:ev3c0101Bespeak -> result:bespeak sendSocket fail! "
					+ e.getMessage());
		} catch (CreateConnectionFailException e) {
			json.setCode("400"); // 失败错误码
			json.setMsg("chargerId " + chargerId + " ev3c0101Bespeak sendSocket fail " + e.getMessage());
			log.error("chargerId " + chargerId
					+ " Class:OmsBespeakServiceImpl -> method:ev3c0101Bespeak -> result:bespeak sendSocket fail! "
					+ e.getMessage());
		} catch (DuplicateInstructionException e) {
			log.error("Send message failure, repeat instruction! e = " + e.getMessage(), e);
			json.setCode(OmsConstant.ErrorCodeEnum.BespeakResultChargerBespeaked.value()); // 失败错误码
			json.setMsg("chargerId " + chargerId + " ev3c0101Bespeak sendSocket fail " + e.getMessage());
			log.error("chargerId " + chargerId
					+ " Class:OmsBespeakServiceImpl -> method:ev3c0101Bespeak -> result:bespeak sendSocket fail! "
					+ e.getMessage());
		}

		return json;
	}

	private JsonCommon<String> ev3c0102Bespeak(Map<String, String> map, String data) {
		return ev3c0101Bespeak(map, data);
	}

	private JsonCommon<String> ev3c0103Bespeak(Map<String, String> map, String data) {
		String chargerId, portNo, userCard, bespeakMinute;
		chargerId = map.get("chargerId");
		portNo = map.get("portNo");
		userCard = map.get("userCard");
		bespeakMinute = map.get("bespeakMinute");// 单位：分 例：预约2小时30分钟 bespeakMinute = 150 实际传输数据为：0x96 0x00
		//
		if (bespeakMinute == null) {
			bespeakMinute = String.valueOf(60 * 60 * 6);
		}
		String key = chargerId + portNo + userCard;
		RedisClient.delByKey(key);
		RedisClient.putString(key, bespeakMinute);
		int bespeakMinute_int = Integer.valueOf(bespeakMinute);
		RedisClient.expire(key, bespeakMinute_int * 60 + 600);// 过期时间在原时间基础上加10分钟
		String ev3c_msgBody = portNo + userCard + StringUtil.float10to16ByParamDesc(bespeakMinute, 1, 4);// 00表示A口，01表示B口
		String ev3c_msgHeader = "68" + StringUtil.ev3cMsgBodyBin(ev3c_msgBody) + "01" + "000000" + "0001" + chargerId
				+ "14" + StringUtil.now14time();
		// StringUtil.sendSocket(msgHeader + msgBody);//
		try {
			ev3cMessageService.sendNoWait(ev3c_msgHeader + ev3c_msgBody, chargerId);
		} catch (RetryFailException e) {
			e.printStackTrace();
			json.setCode("400");
			json.setMsg("chargerId " + chargerId + " bespeak sendSocket fail " + e.getMessage());
			return json;
		} catch (CreateConnectionFailException e) {
			e.printStackTrace();
			json.setCode("400");
			json.setMsg("chargerId " + chargerId + " cancelBespeakReturn sendSocket fail " + e.getMessage());
			return json;
		} catch (DuplicateInstructionException e) {
			log.error("Send message failure, repeat instruction! e = " + e.getMessage(), e);
			json.setCode("400");
			json.setMsg("chargerId " + chargerId + " cancelBespeakReturn sendSocket fail " + e.getMessage());
			return json;
		}
		JsonCommon<String> json = new JsonCommon<String>();
		json.setCode("200");
		json.setMsg(chargerId + " bespeak sendSocket success");
		return json;
	}

	private JsonCommon<String> ev3c0201Bespeak(Map<String, String> map) throws Exception {
		String chargerId, userCard, frameCode, chargerType = "", encryption, msg;

		log.info(map);
		frameCode = "11";
		chargerId = map.get("chargerId");
		int portNo = Integer.valueOf(map.get("portNo"));
		userCard = map.get("userCard");
		encryption = map.get("encryption");
		if (StringUtil.isBlank(chargerId) || !StringUtil.isNumeric(map.get("portNo")) || StringUtil.isBlank(userCard))
			throw new BizException("Charger id do not exist");

		if (StringUtil.isBlank(encryption)) {
			encryption = "00";
		}

		OmsCharger charger_query = new OmsCharger();
		charger_query.setCharger_id(chargerId);
		OmsCharger charger = omsChargerDao.findOneExample(charger_query, null, null);
		if (charger == null)
			throw new BizException("Charger id do not exist");
		log.info(charger.getCharger_id());

		chargerType = String.valueOf(charger.getCharger_type());
		StringBuffer sql = new StringBuffer();
		sql.append(" select a.online_status, a.charge_status from oms_charger_state_alternate a ");
		sql.append(" where a.charger_id = ? and a.port_no = ? ");
		sql.append(" union ALL ");
		sql.append(" select d.online_status, d.charge_status from oms_charger_state_direct d ");
		sql.append(" where d.charger_id = ? and d.port_no = ? ");
		List<Map<String, Object>> list_charger_status = omsChargerDao.findDataBySql(sql.toString(), chargerId, portNo,
				chargerId, portNo);
		if (list_charger_status != null && !list_charger_status.isEmpty()) {
			Map<String, Object> charger_status = list_charger_status.get(0);
			if ((Integer) charger_status.get("online_status") != 1
					|| (Integer) charger_status.get("charge_status") != 0)
				throw new BizException(
						MessageFormat.format("Charger status wrong online_status = {0}, charge_status = {1}",
								charger_status.get("online_status"), charger_status.get("charge_status")));
		}

		log.info("Valid status");

		if (!this.checkBespeakOrderNoPayInfo(userCard) || !this.checkChargerOrderNoPayInfo(userCard)) {
			json.setCode(OmsConstant.ErrorCodeEnum.BespeakResultExistNotPayOrder.value()); // 失败错误码
			json.setMsg("chargerId " + chargerId + " userCard " + userCard + " Exist not pay order!");
			log.error("chargerId " + chargerId + " userCard " + userCard
					+ " Class:OmsBespeakServiceImpl -> method:ev3c0201Bespeak -> result:Exist not pay order!");
			return json;
		}
		// throw new BizException("There is unpaid order for this card");

		String random_code = Ev3c2EncapsulationServiceImpl.getRandom4int();

		int bespeakMinute = DEFAULT_BESPEAK_MINITUE;// 单位：分 例：预约2小时30分钟 bespeakMinute = 150 实际传输数据为：0x96 0x00

		// RedisClient.expire(key, bespeakMinute_int * 60 + 600);//过期时间在原时间基础上加10分钟
		String ev3c_msgBody = userCard + StringUtil.float10to16ByParamDesc(String.valueOf(bespeakMinute), 1, 4)
				+ random_code;// 00表示A口，01表示B口

		msg = messageWapper.wrapSendingMsg(ev3c_msgBody, frameCode, chargerId, chargerType, String.valueOf(portNo),
				encryption);

		String key = msg.substring(32, 50);// 以开始预约作为key放入redis中

		// 写数据库
		OmsChargerBespeakBillRecord billRecord = new OmsChargerBespeakBillRecord();
		// 规则：桩号+端口号+14位时间，其中端口号为两位，以01开始。
		String bespeak_jrnl = "";

		bespeak_jrnl = chargerId + String.format("%02d", portNo) + serialGenerater.generateSerialNo();// portNo应该是2位

		billRecord.setBespeak_jrnl(bespeak_jrnl);
		billRecord.setOms_msg_bespeak_jrnl(key);
		billRecord.setUser_pay_card(userCard);
		billRecord.setPort_no(portNo);
		billRecord.setStart_time(new Date());
		billRecord.setStation_id(charger.getStation_id());

		billRecord.setCharger_id(chargerId);
		billRecord.setIs_done(0);
		billRecord.setStatus(OmsConstant.BespeakStatus.Reserving);
		billRecord.setValid_flag(1);
		omsChargerBespeakBillRecordDao.save(billRecord);

		log.info(billRecord);

		try {
			// RedisClient.getJedisInstance().set(key, JSON.toJSONString(billRecord));
			// RedisClient.expire(key, bespeakMinute * 60 + 600);//过期时间在原时间基础上加10分钟
			ev3c2MessageService.sendNoWait(msg, chargerId);
		} catch (RetryFailException e) {
			log.error(e.getMessage(), e);
			throw e;
		} catch (CreateConnectionFailException e) {
			log.error(e.getMessage(), e);
			throw e;
		}
		JsonCommon<String> json = new JsonCommon<>();
		json.setCode("200");
		json.setMsg(chargerId + " bespeak sendSocket success");
		return json;
	}

	@Override
	public JsonCommon<String> cancelBespeak(Map<String, String> map) throws Exception {

		protocol_type = map.get("protocol_type");
		protocol_version = map.get("protocol_version");
		String data = map.get("data");
		switch (protocol_type) {
		case "1":
			ev3c_frameCode = "14";
			switch (protocol_version) {
			case "0101":
				json = ev3c0101CancelBespeak(map, data);
				break;
			case "0102":
				json = ev3c0102CancelBespeak(map, data);
				break;
			// case "0103":
			// json = ev3c0103CancelBespeak(map, data);
			// break;
			case "0201":
				json = ev3c0201CancelBespeak(map, data);
				break;
			default:
				break;
			}
			break;
		default:
			break;
		}
		return json;
	}

	/**
	 * 针对0101或0102 版本协议 执行流程如下: 取消预约(不充电): 1.判断当前枪口状态,如果为非预约中,则直接返回接口。
	 * 2.更新预约记录表(取消预约中) 3.下发报文
	 *
	 * 取消预约如果是转为充电,则不调用订单服务器,待充电完成后生成一笔订单(包括充电和预约信息)
	 *
	 * @param map
	 * @param data
	 * @return
	 */
	private JsonCommon<String> ev3c0101CancelBespeak(Map<String, String> map, String data) {
		log.info("Receive response message from cancelBespeak" + new Date().getTime());
		String chargerId, portNo, userCard, bespeakStartSerialNumber;
		chargerId = map.get("chargerId");
		portNo = map.get("portNo");
		userCard = map.get("userCard");
		bespeakStartSerialNumber = map.get("bespeakStartSerialNumber");
		if (StringUtil.isBlank(chargerId) || !StringUtil.isNumeric(map.get("portNo")) || StringUtil.isBlank(userCard)) {
			json.setCode(OmsConstant.ErrorCodeEnum.MessageMissParam.value());
			json.setMsg(OmsConstant.ErrorCodeEnum.MessageMissParam.desc());
			log.error("chargerId " + chargerId
					+ " Class:OmsBespeakServiceImpl -> method:ev3c0101CancelBespeak -> result:Charger id do not exist!");
			return json;
		}

		portNo = Ev3cEncapsulationServiceImpl.portNoWithDb(portNo);
		// 1.判断当前枪口状态,如果为非预约中,则直接返回接口
		// [判断该枪口状态,若为空闲状态可预约成功(预约采用独占试,考虑到并发,查询枪口状态和入库两个操作必须控制在同一把锁来处理,防止脏数据)]
		OmsCharger charger_query = new OmsCharger();
		charger_query.setCharger_id(chargerId);
		int port_no = Integer.parseInt(portNo, 2);
		OmsCharger charger = (OmsCharger) omsChargerDao.findOneExample(charger_query, null, null);
		/** 0:空闲 1:预约 2:充电 3:故障 4:占用中(针对双枪单充等情况) 5:刷卡中 8:离线 */
		int chargeStatus = 0; // 当前桩,对应枪口状态
		int chargerType = 1; // 1:直流 2:交流 3:混合
		OmsChargerStateDirect directState = null; // 直流表信息
		OmsChargerStateAlternate alternateState = null; // 交流表信息

		log.info("Receive response message from cancelbespeak(charger_query)");

		// 2.1查询枪口当前状态
		if (charger.getCharger_type() != null) {
			chargerType = charger.getCharger_type();
			switch (chargerType) { // 1:直流 2:交流 3:混合
			case 1:
				OmsChargerStateDirect directState_query = new OmsChargerStateDirect();
				directState_query.setPort_no(port_no);
				directState_query.setCharger_id(map.get("chargerId"));
				directState = (OmsChargerStateDirect) omsChargerStateDirectDao.findOneExample(directState_query, null,
						null);
				chargeStatus = directState.getCharge_status();
				directState.setBespeak_jrnl(null); // 下发报文预约开始流水号(报文开始预约流水号,系统生成,:格式为:YYYY-MM-DD-HH-MI-SS加上四位序号 例如：0x20
													// 0x15 0x05 0x10 0x21 0x45
													// 0x34,0x00,0x00表示2015年5月10日21点击5分34秒第一个流水号(同一时刻自增))
				directState.setUser_pay_card(null);
				omsChargerStateDirectDao.updateObject(directState);
				break;
			case 2:
				OmsChargerStateAlternate alternateState_query = new OmsChargerStateAlternate();
				alternateState_query.setPort_no(port_no);
				alternateState_query.setCharger_id(chargerId);
				alternateState = omsChargerStateAlternateDao.findOneExample(alternateState_query, null, null);
				chargeStatus = alternateState.getCharge_status();
				alternateState.setBespeak_jrnl(null); // 下发报文预约开始流水号(报文开始预约流水号,系统生成,:格式为:YYYY-MM-DD-HH-MI-SS加上四位序号
														// 例如：0x20 0x15 0x05 0x10 0x21 0x45
														// 0x34,0x00,0x00表示2015年5月10日21点击5分34秒第一个流水号(同一时刻自增))
				alternateState.setUser_pay_card(null);
				omsChargerStateDirectDao.updateObject(alternateState);
				break;
			default:
				break;
			}

			// 3.处理预约记录表,更新状态
			OmsChargerBespeakBillRecord bespeakBillRecord_query = new OmsChargerBespeakBillRecord();
			if (StringUtil.isEmpty(bespeakStartSerialNumber)) { // true:为空 false:不为空, 接口取消预约
				bespeakBillRecord_query.setOms_msg_bespeak_jrnl(bespeakStartSerialNumber);
			} else {
				bespeakBillRecord_query.setUser_pay_card(userCard);
				bespeakBillRecord_query.setStatus(2); // 预约状态:1:预约中 2:已预约 3:取消预约中 4:已取消预约 5:充电(流程1:1-2-3-4, 流程2:1-2-5)
				bespeakBillRecord_query.setCharger_id(chargerId);
				bespeakBillRecord_query.setPort_no(port_no);
			}
			OmsChargerBespeakBillRecord bespeakBillRecord = omsChargerBespeakBillRecordDao
					.findOneExample(bespeakBillRecord_query, "start_time", "desc");
			if (!StringUtil.objectIsNull(bespeakBillRecord) && bespeakBillRecord.getStatus() == 2) { // 状态为已预约,则可以取消预约
				bespeakBillRecord.setStatus(3); // 预约状态:1:预约中 2:已预约 3:取消预约中 4:已取消预约 5:充电(流程1:1-2-3-4, 流程2:1-2-5)
				bespeakBillRecord.setOms_msg_bespeak_end_jrnl(serialGenerater.generateSerialNo());
				omsChargerBespeakBillRecordDao.updateObject(bespeakBillRecord); // 更新状态
			} else { // 否则:接口直接返回取消预约失败
				json.setCode(OmsConstant.ErrorCodeEnum.CancelBespeakResultNoBespeak.value());
				json.setMsg("chargerId " + chargerId + "userCard " + userCard
						+ " ev3c0101Bespeak: The charger no bespeak!"); // 带卡号
				log.error("chargerId " + chargerId
						+ " Class:OmsBespeakServiceImpl -> method:ev3c0101Bespeak -> result:The charger no bespeak!");
			}

			// 3.下发报文
			portNo = Ev3cEncapsulationServiceImpl.portNoWithMsg(portNo);
			String ev3c_msgBody = (portNo.length() == 1 ? "0".concat(portNo) : portNo).concat(userCard); // 00表示A口,01表示B口
			String ev3c_msgHeader = "68" + StringUtil.ev3cMsgBodyBin(ev3c_msgBody) + "01" + "000000" + "0001"
					+ chargerId + "16" + StringUtil.now14time();
			try {
				log.info("Send message to cancelBespeak sendNoWait! curTime = " + new Date().getTime());
				ev3cMessageService.sendNoWait(ev3c_msgHeader + ev3c_msgBody, chargerId);
			} catch (RetryFailException e) {
				json.setCode("400");
				json.setMsg("chargerId " + chargerId + " cancelBespeak sendSocket fail! " + e.getMessage());
				log.error("chargerId " + chargerId
						+ " Class:OmsBespeakServiceImpl -> method:ev3c0101CancelBespeak -> result:cancelBespeak sendNoWait fail!"
						+ e.getMessage());
				return json;
			} catch (CreateConnectionFailException e) {
				json.setCode("400");
				json.setMsg("chargerId " + chargerId + " cancelBespeakReturn sendSocket fail " + e.getMessage());
				log.error("chargerId " + chargerId
						+ " Class:OmsBespeakServiceImpl -> method:ev3c0101CancelBespeak -> result:cancelBespeak sendNoWait fail!"
						+ e.getMessage());
				return json;
			} catch (DuplicateInstructionException e) {
				log.error("Send message failure, repeat instruction! e = " + e.getMessage(), e);
				json.setCode("400");
				json.setMsg("chargerId " + chargerId + " cancelBespeakReturn sendSocket fail " + e.getMessage());
				log.error("chargerId " + chargerId
						+ " Class:OmsBespeakServiceImpl -> method:ev3c0101CancelBespeak -> result:cancelBespeak sendNoWait fail!"
						+ e.getMessage());
				return json;
			}

			json.setCode("200");
			json.setMsg("bespeak sendSocket success");
			json.setPojo(ev3c_msgHeader + ev3c_msgBody);
			log.debug("chargerId " + chargerId
					+ " Class:OmsBespeakServiceImpl -> method:ev3c0101CancelBespeak -> result:cancelBespeak sendOrderToAppServer success, cancelBespeak sendSocket success!");
		}
		return json;
	}

	private JsonCommon<String> ev3c0102CancelBespeak(Map<String, String> map, String data) {
		return ev3c0101CancelBespeak(map, data);
	}

	private JsonCommon<String> ev3c0103CancelBespeak(Map<String, String> map, String data) {
		return ev3c0101CancelBespeak(map, data);
	}

	private synchronized JsonCommon<String> ev3c0201CancelBespeak(Map<String, String> map, String data)
			throws Exception {
		log.info("Cancel reservation");

		String bespeakStartSerialNumber = map.get("bespeakStartSerialNumber");
		log.info(bespeakStartSerialNumber);

		OmsChargerBespeakBillRecord billRecord_query = new OmsChargerBespeakBillRecord();
		billRecord_query.setOms_msg_bespeak_jrnl(bespeakStartSerialNumber);
		billRecord_query.setStatus(OmsConstant.BespeakStatus.Reserved);
		OmsChargerBespeakBillRecord billRecord = omsChargerBespeakBillRecordDao.findOneExample(billRecord_query, null,
				null);
		if (billRecord == null)
			throw new BizException("Reservation record not found");
		log.info("reservation record found");

		String userCard = billRecord.getUser_pay_card();
		String chargerId = billRecord.getCharger_id();
		Integer portNo = billRecord.getPort_no();

		String frameCode = "12";
		String encryption = "00";

		String ev3c_msgBody = userCard + bespeakStartSerialNumber;// 00表示A口，01表示B口

		OmsCharger charger_query = new OmsCharger();
		charger_query.setCharger_id(chargerId);
		OmsCharger charger = omsChargerDao.findOneExample(charger_query, null, null);
		if (charger == null)
			throw new BizException("Charger is not found ");
		log.info(charger.getCharger_id());

		if (StringUtils.isNotEmpty(billRecord.getOrder_no()))
			throw new BizException("Cannot cancel this reservation because it is already generated as an order");
		log.info("Haven't create a order");

		String msg = messageWapper.wrapSendingMsg(ev3c_msgBody, frameCode, chargerId,
				String.valueOf(charger.getCharger_type()), portNo.toString(), encryption);

		billRecord.setOms_msg_bespeak_end_jrnl(msg.substring(32, 50));
		billRecord.setStatus(OmsConstant.BespeakStatus.ReservationCancelling);
		omsChargerBespeakBillRecordDao.updateObject(billRecord);

		log.info(billRecord);
		try {
			ev3c2MessageService.sendNoWait(msg, chargerId);
		} catch (RetryFailException e) {
			log.error(e.getMessage(), e);
			throw e;
		} catch (CreateConnectionFailException e) {
			log.error(e.getMessage(), e);
			throw e;
		}
		JsonCommon<String> json = new JsonCommon<String>();
		json.setCode("200");
		json.setMsg("bespeak sendSocket success");
		log.info(json);
		return json;
	}

	// 2.0协议中的预约返回就表示预约已经成功，桩状态已经改变。预约下发的时候在预约费用表中生成一条记录，记录下发的流水号和表中生成的流水号。下发流水号由Java控制唯一。
	// 预约下发时已经把预约信息存入表中，不在redis中做处理
	@Override
	public void ev3c02bespeakReturn(ChargerReplyMsgHeader header) throws Exception {
		log.info("Receive response message from charger");
		log.debug(JSON.toJSON(header));

		String omsSerialNumber = header.getServerSerialNo();

		// 之前是char_bespeak_record，现在这个表已经被合并到char_bespeak_bill_record[预约费用记录表]中了。
		OmsChargerBespeakBillRecord billRecord_query = new OmsChargerBespeakBillRecord();
		billRecord_query.setOms_msg_bespeak_jrnl(omsSerialNumber);
		OmsChargerBespeakBillRecord billRecord = omsChargerBespeakBillRecordDao.findOneExample(billRecord_query, null,
				null);
		if (billRecord == null)
			throw new BizException("Reservation record not found");

		log.info("reservation record exist");

		String chargerId = billRecord.getCharger_id();
		int port_no = billRecord.getPort_no();

		OmsCharger charger_query = new OmsCharger();
		charger_query.setCharger_id(chargerId);
		OmsCharger charger = omsChargerDao.findOneExample(charger_query, null, null);
		if (charger == null)
			throw new BizException("Charger not found");

		log.info("charger exist");

		billRecord.setStatus(OmsConstant.BespeakStatus.Reserved);// 预约已回复，桩状态为预约中
		omsChargerBespeakBillRecordDao.updateObject(billRecord);
		// 更新状态 oms_charger_state_alternate[交流充电桩状态表]
		// oms_charger_state_direct[直流充电桩状态表]
		// 报文中需要有直流和交流的区别，如果是为了中新用的，就应该是oms_charger_state_direct[直流充电桩状态表]
		if (charger.getCharger_type() != null) {
			int chargerType = charger.getCharger_type();
			log.info(chargerType);
			switch (chargerType) {// 1--直流 2--交流 3--混合
			case 1:
				OmsChargerStateDirect directState_query = new OmsChargerStateDirect();
				directState_query.setPort_no(port_no);
				directState_query.setCharger_id(header.getChargerId());
				OmsChargerStateDirect directState = omsChargerStateDirectDao.findOneExample(directState_query, null,
						null);
				directState.setCharge_status(1);
				directState.setOnline_status(1);
				directState.setBespeak_jrnl(billRecord.getBespeak_jrnl());
				directState.setUser_pay_card(billRecord.getUser_pay_card());
				omsChargerStateDirectDao.updateObject(directState);
				if (charger.getIs_parallel_charge() == 0) {
					omsChargerStateDirectDao
							.exec("update oms_charger_state_direct set charge_status = 4 where charger_id = '"
									+ chargerId + "' and port_no <> " + port_no);
				}
				break;
			case 2:
				OmsChargerStateAlternate alternateState_query = new OmsChargerStateAlternate();
				alternateState_query.setPort_no(port_no);
				alternateState_query.setCharger_id(chargerId);
				OmsChargerStateAlternate alternateState = omsChargerStateAlternateDao
						.findOneExample(alternateState_query, null, null);
				alternateState.setCharge_status(1);
				alternateState.setOnline_status(1);
				alternateState.setBespeak_jrnl(billRecord.getBespeak_jrnl());
				alternateState.setUser_pay_card(billRecord.getUser_pay_card());
				omsChargerStateAlternateDao.updateObject(alternateState);
				if (charger.getIs_parallel_charge() == 0) {
					omsChargerStateDirectDao
							.exec("update oms_charger_state_alternate set charge_status = 4 where charger_id = '"
									+ chargerId + "' and port_no <> " + port_no);
				}
				break;
			default:
				break;
			}
		}

		// api_v3.php中的1458行 HttpGetRequest 是调用AS的接口 dzAppURL,通知
		log.info("Notify AS");
		// 通知appServer start
		try {
			notifyOnReservationSuccess(AppServerConstant.STATION_UPDATE_NOTIFY_ACTION_RESERVATION, billRecord, charger);
		} catch (BizException e) {
			log.error(e.getMessage(), e);
		}
		log.info("After Notify");

	}

	// 开始预约下发时不存预约开始时间，开始预约返回时存预约开始时间，预约时长。取消预约下发时不存预约结束时间，返回时存预约结束时间。
	@Override
	public void ev3c2cancelBespeakReturn(ChargerReplyMsgHeader header) throws Exception {

		log.info("reservation return");
		String omsSerialNumber = header.getServerSerialNo();
		log.info(omsSerialNumber);

		OmsChargerBespeakBillRecord omsChargerBespeakBillRecord_query = new OmsChargerBespeakBillRecord();
		omsChargerBespeakBillRecord_query.setOms_msg_bespeak_end_jrnl(omsSerialNumber);
		OmsChargerBespeakBillRecord bespeakBill = omsChargerBespeakBillRecordDao
				.findOneExample(omsChargerBespeakBillRecord_query, null, null);
		if (bespeakBill == null)
			throw new BizException("Reservation record not found");

		String chargerId = bespeakBill.getCharger_id();
		Integer port_no = bespeakBill.getPort_no();

		OmsCharger charger_query = new OmsCharger();
		charger_query.setCharger_id(chargerId);
		OmsCharger charger = omsChargerDao.findOneExample(charger_query, null, null);
		if (charger == null || charger.getCharger_type() == null)
			throw new BizException("Charger not found or charger type is empty");

		int chargerType = charger.getCharger_type();
		log.info(chargerType);
		switch (chargerType) {// 1--直流 2--交流 3--混合
		case 1:
			OmsChargerStateDirect directState_query = new OmsChargerStateDirect();
			directState_query.setPort_no(port_no);
			directState_query.setCharger_id(chargerId);
			OmsChargerStateDirect directState = omsChargerStateDirectDao.findOneExample(directState_query, null, null);
			directState.setCharge_status(0);
			directState.setOnline_status(1);
			directState.setBespeak_jrnl("");
			omsChargerStateDirectDao.updateObject(directState);
			if (charger.getIs_parallel_charge() == 0) {
				omsChargerStateDirectDao
						.exec("update oms_charger_state_direct set charge_status = 4 where charger_id = '" + chargerId
								+ "' and port_no <> " + port_no);
			}
			break;
		case 2:
			OmsChargerStateAlternate alternateState_query = new OmsChargerStateAlternate();
			alternateState_query.setPort_no(port_no);
			alternateState_query.setCharger_id(chargerId);
			OmsChargerStateAlternate alternateState = omsChargerStateAlternateDao.findOneExample(alternateState_query,
					null, null);
			alternateState.setCharge_status(0);
			alternateState.setOnline_status(1);
			alternateState.setBespeak_jrnl("");
			omsChargerStateAlternateDao.updateObject(alternateState);
			if (charger.getIs_parallel_charge() == 0) {
				omsChargerStateDirectDao
						.exec("update oms_charger_state_alternate set charge_status = 0 where charger_id = '"
								+ chargerId + "' and port_no <> " + port_no);
			}
			break;
		default:
			break;
		}

		Date now = new Date();
		// String userCard = bespeakBill.getUser_pay_card();

		// String cardType = CardUtils.generateCardType(userCard);

		BigDecimal totalAmount = BigDecimal.ZERO;

		// 查询卡号是不是在白名单里面。
		OmsChargerOfflineWhitelist whitelist_query = new OmsChargerOfflineWhitelist();
		whitelist_query.setCharger_id(chargerId);
		whitelist_query.setUser_pay_card(bespeakBill.getUser_pay_card());
		OmsChargerOfflineWhitelist whitelist = omsChargerOfflineWhitelistDao.findOneExample(whitelist_query, null,
				null);
		List<PaymentDetail> reservationFeeDetails = new ArrayList<>();
		if (whitelist == null)
			totalAmount = priceService.computeFee(charger.getRate_schema_bespeak_fee(), bespeakBill.getStart_time(),
					now, reservationFeeDetails);

		if (totalAmount.compareTo(new BigDecimal(OrderConstant.UPLOAD_BILL_CHARGE_BESPEAK_MAX)) > 0) {
			// 入库oms_charger_error_record[故障记录表]
			log.error("Bespeak fee exception!");
			OmsChargerErrorRecord record = new OmsChargerErrorRecord();
			record.setCharger_id(chargerId);
			record.setError_code("error");
			record.setError_msg("Bespeak fee exception!");
			record.setStatus(0); // 0:未处理,1:已处理
			record.setValid_flag(1);
			record.setCreate_oper_id("000");
			record.setCreate_time(new Date());
			omsChargerErrorRecordService.add(record);
			throw new BizException("Bespeak fee exception " + totalAmount);
		}

		bespeakBill.setActual_end_time(new Date());
		bespeakBill.setStatus(OmsConstant.BespeakStatus.ReservationCancelled);
		bespeakBill.setBespeak_deal_before(totalAmount.floatValue());

		RetVO.CreatedOrderVO createdOrderVO = this.createOrderWhenCancelReservation(bespeakBill, charger,
				reservationFeeDetails);

		bespeakBill.setOrder_no(createdOrderVO.getOrderNo());
		bespeakBill.setBespeak_deal_charge(createdOrderVO.getTotalFee().floatValue());
		omsChargerBespeakBillRecordDao.updateObject(bespeakBill);

		log.info(bespeakBill);

		try {
			notifyOnReservationSuccess(AppServerConstant.STATION_UPDATE_NOTIFY_ACTION_CANCEL_RESERVATION, bespeakBill,
					charger);
			notifyOnReservationFee(createdOrderVO, bespeakBill);
		} catch (BizException e) {
			log.error(e.getMessage(), e);
		}
	}

	/*****************
	 * 20160411 perlin add begin
	 **************************************/
	@Override
	public JsonForList<OmsChargerBespeakBillRecord> findBespeakBySeriaNoAndUserCard(String userPayCard,
			String bespeak_serial_number) {
		String conditonSql = " a where a.user_pay_card = '" + userPayCard + "' and a.bespeak_jrnl='"
				+ bespeak_serial_number + "'";
		OmsChargerBespeakBillRecord queryObj = this.omsChargerBespeakBillRecordDao
				.findOneExampleByCondition(new OmsChargerBespeakBillRecord(), conditonSql);
		JsonForList<OmsChargerBespeakBillRecord> retJsons = new JsonForList<OmsChargerBespeakBillRecord>();
		if (null == queryObj) {
			retJsons.setCode(MsgCodeEnum.AS_RPC_PARAM_FORMAT_ERROR.getMsgCode());
			retJsons.setMsg(MsgCodeEnum.AS_RPC_PARAM_FORMAT_ERROR.getMsgInfo());
			return retJsons;
		}
		List<OmsChargerBespeakBillRecord> lsRecords = new ArrayList<OmsChargerBespeakBillRecord>();
		lsRecords.add(queryObj);

		retJsons.setCode(MsgCodeEnum.SUCCESS.getMsgCode());
		retJsons.setMsg(MsgCodeEnum.SUCCESS.getMsgInfo());
		retJsons.setList(lsRecords);
		return retJsons;
	}

	@Override
	public JsonForList<OmsChargerBespeakBillRecord> findListByUserCard(String userPayCard, String pageNo,
			String pageSize) {
		String conditonSql = " a where a.user_pay_card = '" + userPayCard + "'";
		JsonForList<OmsChargerBespeakBillRecord> retJsons = new JsonForList<OmsChargerBespeakBillRecord>();
		retJsons.setCode(MsgCodeEnum.SUCCESS.getMsgCode());
		retJsons.setMsg(MsgCodeEnum.SUCCESS.getMsgInfo());
		retJsons.setList(this.omsChargerBespeakBillRecordDao.findListByPageAndGroupAndOrderAndCondition(
				new OmsChargerBespeakBillRecord(), conditonSql, Integer.valueOf(pageNo), Integer.valueOf(pageSize),
				null, null, null));
		return retJsons;
	}

	/*****************
	 * 20160411 perlin add end
	 **************************************/

	/**
	 * 校验电桩回复报文中响应码
	 * 
	 * @return boolean
	 */
	public static boolean checkChargerReplyMessageStatus(String responseCode) {
		boolean flag = true;
		// 1.判断回复报文中是否为正常返回,如果响应码不为000000,则做相应处理(记录入故障记录表,再回调);否则进入第二步。
		if (responseCode == null || "".equals(responseCode) || !responseCode.equals("000000")) {
			flag = false;
		}
		return flag;
	}

	/**
	 * 校验卡号类型(1:app 2:)
	 * 
	 * @return boolean
	 */
	public static int checkUserCardType(String userCard) {
		int result = 0;
		if (userCard.startsWith("18808") && !userCard.substring(0, 9).equals("188089999")) { // 08:线上卡
			result = 1; // app卡号
		} else if (userCard.startsWith("18806") && !userCard.substring(0, 9).equals("188060028")) { // 06:现金卡
			result = 2;
		} else if (userCard.startsWith("18805") && !userCard.substring(0, 9).equals("188050028")) { // 05 身份认证卡
			result = 3;
		}
		return result;
	}

	@Override
	public List<OrdersStatus> getOrdersStatus(String orderNos) throws BizException {
		log.info("Send to  message from  orderRpcClient.createOrder! curTime = " + new Date().getTime());
		RetVO retVO = orderRpcClient.queryOrderStatus(orderNos);
		if (retVO == null || !retVO.getRetCode().equals(RetVO.SuccessCode))
			throw new BizException("query order status error via order server while querying orders ");

		String bizData = retVO.getBizData().toString();
		log.debug(bizData);
		List<OrdersStatus> listTmp = JSON.parseArray(bizData, OrdersStatus.class);
		return listTmp;
	}

	@Override
	public boolean updateOrdersStatus(String orderNos, String type) {
		String sql = "";
		if ("1".equals(type)) {
			sql = "update oms_charger_bespeak_bill_record set is_done=1,status=4 where order_no in (" + orderNos + ")"; // 预约订单
		} else if ("2".equals(type)) {
			sql = "update oms_charger_charge_bill_record set status=6,offline_is_pay=3 where order_no in (" + orderNos
					+ ")"; // 充电订单
		}

		return omsChargerBespeakBillRecordDao.exec(sql);
	}

	/**
	 * 校验预约订单没有支付信息
	 * 
	 * @return true:不存在没有支付订单
	 */
	public boolean checkBespeakOrderNoPayInfo(String userCard) {
		OmsChargerBespeakBillRecord bespeakBillRecord_query = new OmsChargerBespeakBillRecord();
		// bespeakBillRecord_query.setCharger_id(chargerId);
		bespeakBillRecord_query.setUser_pay_card(userCard);
		// bespeakBillRecord_query.setPort_no(port_no);
		bespeakBillRecord_query.setIs_done(0); // 是否完成订单(0:未完成,1:完成)
		bespeakBillRecord_query.setValid_flag(1);
		List<OmsChargerBespeakBillRecord> omsChargerBespeakBillRecordList = omsChargerBespeakBillRecordDao
				.findExample(bespeakBillRecord_query, null, null, null, null);

		String orderNoPayList = ""; // 组装订单号发送到订单服务器列表
		List<OrdersStatus> resultList = null;
		int bespeakListFlag = 0; // 未支付状态数量标记
		if (omsChargerBespeakBillRecordList != null && omsChargerBespeakBillRecordList.size() > 0) { // 存在未支付订单(1.预约)
			for (int i = 0; i < omsChargerBespeakBillRecordList.size(); i++) {
				if (omsChargerBespeakBillRecordList.get(i).getOrder_no() != null) { // 订单号不为空,组装
					orderNoPayList = orderNoPayList.concat(omsChargerBespeakBillRecordList.get(i).getOrder_no())
							.concat(",");
				}
			}
			if (orderNoPayList.length() > 0) {
				orderNoPayList = orderNoPayList.substring(0, orderNoPayList.length() - 1); // 处理最后一个 ,
				try {
					// 发送订单服务器,获取支付信息
					resultList = getOrdersStatus(orderNoPayList); // 调用订单服务器接口
					for (OrdersStatus ordersStatus : resultList) {
						if (ordersStatus.getStatusCode().equals("7")) { // (7, "已支付,已完成") 入库处理
							// pengyu modify 20180428 节约时间，每天有定时任务，这里就不做支付状态更新了
							// OmsChargerBespeakBillRecord bespeakBillRecord_temp = new
							// OmsChargerBespeakBillRecord();
							// bespeakBillRecord_temp.setOrder_no(ordersStatus.getOrderNo());
							// OmsChargerBespeakBillRecord bespeakBillRecord =
							// omsChargerBespeakBillRecordDao.findOneExample(bespeakBillRecord_temp,null,null);
							// bespeakBillRecord.setIs_done(1); // 是否完成订单(0:未完成,1:完成)
							// bespeakBillRecord.setStatus(4); // 预约状态:1:预约中 2:已预约 3:取消预约中 4:已取消预约
							// 5:充电(流程1:1-2-3-4, 流程2:1-2-5)
							// omsChargerBespeakBillRecordDao.updateObject(bespeakBillRecord);
						} else {
							// bespeakListFlag ++;
							bespeakListFlag = 1;// pengyu modify
							break;
						}
					}
					if (bespeakListFlag != 0) { // 存在未支付订单(1.预约),直接返回
						json.setCode(OmsConstant.ErrorCodeEnum.BespeakResultExistNotPayOrder.value()); // 失败错误码
						json.setMsg("userCard " + userCard + " Exist not pay order!");
						log.error("userCard " + userCard
								+ " Class:OmsBespeakServiceImpl -> method:ev3c0101Bespeak -> result:Exist not pay order!");
						return false;
					}
				} catch (BizException e) {
					json.setCode(OmsConstant.ErrorCodeEnum.BespeakResultExistNotPayOrder.value());
					json.setMsg("userCard " + userCard + "userCard " + userCard
							+ " ev3c0101Bespeak:Exist not pay order! " + e.getMessage()); // 带卡号
					log.error("userCard " + userCard
							+ " Class:OmsBespeakServiceImpl -> method:ev3c0101Bespeak -> result:Exist not pay order! "
							+ e.getMessage());
					return false;
				}
			}
		}
		return true;
	}

	/**
	 * 校验充电订单没有支付信息
	 * 
	 * @return true:不存在没有支付订单
	 */
	public boolean checkChargerOrderNoPayInfo(String userCard) {
		OmsChargerChargeBillRecord billRecord_query = new OmsChargerChargeBillRecord();
		// billRecord_query.setCharger_id(chargerId);
		billRecord_query.setUser_pay_card(userCard);
		// billRecord_query.setPort_no(port_no);
		billRecord_query.setValid_flag(1);
		billRecord_query.setOffline_is_pay(2); // 0:线下未结算,1:线下已结算,2:线上未结算,3.线上已结算
		List<OmsChargerChargeBillRecord> omsChargerChargeBillRecordList = omsChargerChargeBillRecordDao
				.findExample(billRecord_query, null, null, null, null);
		String orderNoPayList = ""; // 组装发送到订单服务器列表
		List<OrdersStatus> resultList = null;
		int chargeListFlag = 0; // 支付标记
		if (omsChargerChargeBillRecordList != null && omsChargerChargeBillRecordList.size() > 0) { // 存在未支付订单(1.预约)
			for (int i = 0; i < omsChargerChargeBillRecordList.size(); i++) {
				if (omsChargerChargeBillRecordList.get(i).getOrder_no() != null) { // 订单号不为空,组装
					orderNoPayList = orderNoPayList.concat(omsChargerChargeBillRecordList.get(i).getOrder_no())
							.concat(",");
				}
			}
			if (orderNoPayList.length() > 0) {
				orderNoPayList = orderNoPayList.substring(0, orderNoPayList.length() - 1); // 处理最后一个 ,
				try {
					// 发送订单服务器,获取支付信息
					resultList = getOrdersStatus(orderNoPayList); // 调用订单服务器接口
					for (OrdersStatus ordersStatus : resultList) {
						if (ordersStatus.getStatusCode().equals("7")) { // (7, "已支付,已完成") 入库处理
							// OmsChargerChargeBillRecord chargeBillRecord_temp = new
							// OmsChargerChargeBillRecord();
							// chargeBillRecord_temp.setOrder_no(ordersStatus.getOrderNo());
							// OmsChargerChargeBillRecord chargeBillRecord =
							// omsChargerChargeBillRecordDao.findOneExample(chargeBillRecord_temp,null,null);
							// chargeBillRecord.setOffline_is_pay(3); // 0:线下未结算,1:线下已结算,2:线上未结算,3.线上已结算
							// chargeBillRecord.setStatus(6); // 0:开启充电(已下发指令未回复) 1:充电中(已确认桩回复)
							// 2:电充满未结束(如未拔枪则是此状态) 3:关闭充电(已下发指令) 4:充电结束(桩回复充电结束) 5:已生成账单 6:已结算 7:已退款 8:充电失败
							// omsChargerChargeBillRecordDao.updateObject(chargeBillRecord);
						} else {
							// chargeListFlag ++;
							chargeListFlag = 1;
							break;
						}
					}
					if (chargeListFlag != 0) { // 存在未支付订单(1.预约),直接返回
						json.setCode(OmsConstant.ErrorCodeEnum.BespeakResultExistNotPayOrder.value()); // 失败错误码
						json.setMsg("userCard " + userCard + " Exist not pay order!");
						log.error("userCard " + userCard
								+ " Class:OmsBespeakServiceImpl -> method:ev3c0101Bespeak -> result:Exist not pay order!");
						return false;
					}
				} catch (BizException e) {
					json.setCode(OmsConstant.ErrorCodeEnum.BespeakResultExistNotPayOrder.value());
					json.setMsg("chargerId " + userCard + " ev3c0101Bespeak:Exist not pay order! " + e.getMessage()); // 带卡号
					log.error("chargerId " + userCard
							+ " Class:OmsBespeakServiceImpl -> method:ev3c0101Bespeak -> result:Exist not pay order! "
							+ e.getMessage());
					return false;
				}
			}
		}
		return true;
	}

	private void notifyOnReservationSuccess(String action, OmsChargerBespeakBillRecord bespeakBillRecord,
			OmsCharger charger) throws BizException {
		String userCard = bespeakBillRecord.getUser_pay_card();
		if (CardUtils.generateCardType(userCard).equals(OmsConstant.CardTypeEnum.OnlineApp)) { // APP卡号
			log.info("Receive response message from bespeakReturn(AppReservationNotifyParam)");
			// 通知appServer start
			AppReservationNotifyParam obj = new AppReservationNotifyParam();
			obj.setAction(action);// AppServerConstant.STATION_UPDATE_NOTIFY_ACTION_RESERVATION); // 预约
			obj.setChargerId(bespeakBillRecord.getCharger_id());
			obj.setStationName(charger.getStation_name());
			obj.setSerialNo(charger.getSerial_no());
			obj.setPlugNo(String.valueOf(bespeakBillRecord.getPort_no()));
			obj.setUserCard(bespeakBillRecord.getUser_pay_card());
			obj.setStartTime(bespeakBillRecord.getStart_time().toString());
			obj.setReservationSn(bespeakBillRecord.getBespeak_jrnl());

			log.info("Send message to reservation Notification" + new Date().getTime());
			JsonCommon json = systemAppServerRpcClient.reservationNotify(obj);
			log.info("Send message to reservation Notification return" + new Date().getTime());
			if (!json.getCode().equals(AppServerConstant.RELULT_INFO_APP_SERVIER_NOTIFY_SUCCESS_CODE))
				throw new BizException(json.getCode() + ", " + json.getMsg());
		} else { // TODO peizhide 预留第三方接口
		}
	}

	private void notifyOnReservationFee(RetVO.CreatedOrderVO retVO,
			OmsChargerBespeakBillRecord omsChargerBespeakBillRecord) throws BizException {
		if (CardUtils.generateCardType(omsChargerBespeakBillRecord.getUser_pay_card())
				.equals(OmsConstant.CardTypeEnum.OnlineApp)) { // APP卡号
			log.info("Receive response message from bespeakReturn(AppReservationNotifyParam)");
			// 通知appServer start
			AppOrderNotifyParam appOrderNotifyParam = new AppOrderNotifyParam();
			appOrderNotifyParam.setUserCard(omsChargerBespeakBillRecord.getUser_pay_card());
			appOrderNotifyParam.setOrderNo(retVO.getOrderNo());
			appOrderNotifyParam.setMoney(retVO.getTotalFee().toEngineeringString());
			// 取消预约(pojo中组装预约记录表流水号)
			json.setPojo(omsChargerBespeakBillRecord.toString());
			json = systemAppServerRpcClient.orderNotify(appOrderNotifyParam);
			// 通知appServer end
			if (!json.getCode().equals(AppServerConstant.RELULT_INFO_APP_SERVIER_NOTIFY_SUCCESS_CODE))
				throw new BizException(json.getCode() + ", " + json.getMsg());
		} else { // TODO peizhide 预留第三方接口
		}
	}

	private RetVO.CreatedOrderVO createOrderWhenCancelReservation(OmsChargerBespeakBillRecord bespeakBillRecord,
			OmsCharger charger, List<PaymentDetail> reservationFeeDetails) throws BizException, OmsDaoException {
		log.info("createOrderWhenCancelReservation Create order via order server");
		
		List<OrderBaseData> list = new ArrayList<>();
		OrderBaseData orderBaseData = new OrderBaseData();
		orderBaseData.setCardNo(bespeakBillRecord.getUser_pay_card());
		orderBaseData.setCardType(CardUtils.generateCardType(bespeakBillRecord.getUser_pay_card()));
		orderBaseData.setPayerBalance("0");
		orderBaseData.setAppId(BizSystemCode.DzApp.value());
		orderBaseData.setServiceNo(OrderServiceEnum.Reservation.value());
		orderBaseData.setServiceProviderCode(charger.getOper_merchant_id());
		OmsStation omsStaionQuery = new OmsStation(charger.getStation_id());
		OmsStation omsStaion = omsStationDao.findRecordByPK(omsStaionQuery);
		if(omsStaion!=null){
			orderBaseData.setPlantName(omsStaion.getStation_name());
		}
		orderBaseData.setPlantId(charger.getStation_id());
		orderBaseData.setEquipmentNo(charger.getCharger_id());
		orderBaseData.setAuxEquipmentNo(bespeakBillRecord.getPort_no().toString());
		orderBaseData.setTotalPrice(new BigDecimal(bespeakBillRecord.getBespeak_deal_before()));
		orderBaseData.setBuyNum(new BigDecimal(
				(bespeakBillRecord.getActual_end_time().getTime() - bespeakBillRecord.getStart_time().getTime())
						/ (1000 * 60)));
		orderBaseData.setStartTime(bespeakBillRecord.getStart_time());
		orderBaseData.setEndTime(bespeakBillRecord.getActual_end_time());
		orderBaseData.setPayStatus(0);
		orderBaseData.setMessage(JSON.toJSONString(reservationFeeDetails));
		list.add(orderBaseData);

		log.info("Send to  message from ev3c2cancelBespeakReturn orderRpcClient.createOrder! curTime = "
				+ new Date().getTime());
		RetVO retVO = orderRpcClient.createOrder(list);
		if (retVO == null || !retVO.getRetCode().equals(RetVO.SuccessCode))
			throw new BizException("create order error via order server while cancelling a reservation");

		String bizData = retVO.getBizData().toString();
		log.debug(bizData);
		RetVO.CreatedOrderVO createdOrderVO = JSON.parseObject(bizData, RetVO.CreatedOrderVO.class);
		return createdOrderVO;
	}

	@Override
	public boolean checkOrderNoPay(String userCard) {
		StringBuffer orderNoSB = new StringBuffer(""); // 组装订单号发送到订单服务器列表
		List<String> orderNoList = new ArrayList<>();
		//查询预约账单
		OmsChargerBespeakBillRecord bespeakBillRecord_query = new OmsChargerBespeakBillRecord();
		bespeakBillRecord_query.setUser_pay_card(userCard);
		bespeakBillRecord_query.setIs_done(0); // 是否完成订单(0:未完成,1:完成)
		bespeakBillRecord_query.setValid_flag(1);
		List<OmsChargerBespeakBillRecord> omsChargerBespeakBillRecordList = omsChargerBespeakBillRecordDao
				.findExample(bespeakBillRecord_query, null, null, null, null);
		//查询充电账单
		OmsChargerChargeBillRecord billRecord_query = new OmsChargerChargeBillRecord();
		billRecord_query.setUser_pay_card(userCard);
		billRecord_query.setValid_flag(1);
		billRecord_query.setOffline_is_pay(2); // 0:线下未结算,1:线下已结算,2:线上未结算,3.线上已结算
		List<OmsChargerChargeBillRecord> omsChargerChargeBillRecordList = omsChargerChargeBillRecordDao
				.findExample(billRecord_query, null, null, null, null);
		
		if (!omsChargerBespeakBillRecordList.isEmpty()) { // 存在未支付订单 预约)
			for (int i = 0; i < omsChargerBespeakBillRecordList.size(); i++) {
				if (omsChargerBespeakBillRecordList.get(i).getOrder_no() != null) { // 订单号不为空,组装
					orderNoList.add(omsChargerBespeakBillRecordList.get(i).getOrder_no());
				}
			}
		}
		log.info("omsChargerChargeBillRecordList.size() = "+omsChargerChargeBillRecordList.size());
		if (!omsChargerChargeBillRecordList.isEmpty()) { // 存在未支付订单 充电)
			for (int i = 0; i < omsChargerChargeBillRecordList.size(); i++) {
				if (omsChargerChargeBillRecordList.get(i).getOrder_no() != null) { // 订单号不为空,组装
					orderNoList.add(omsChargerChargeBillRecordList.get(i).getOrder_no());
				}
			}
		}
		for (String orderNo : orderNoList) {
			orderNoSB.append(orderNo + ",");
		}
		log.info("orderNoSB = "+orderNoSB);
		if (orderNoSB.length() > 0) {
			orderNoSB.deleteCharAt(orderNoSB.length() - 1);
			return false;
		} else {
			return true;// 没有订单，返回真
		}
		//20180528 还是把更新订单交给定时任务去做，以免定时任务去抢资源导致死锁
//		try {
//			// 发送订单服务器,获取支付信息
//			List<OrdersStatus> resultList = null;
//			resultList = getOrdersStatus(orderNoSB.toString()); // 调用订单服务器接口
//			log.info("resultList.size() = "+resultList.size()); 
//			for (OrdersStatus ordersStatus : resultList) {
//				log.info("ordersStatus.getOrderNo() = " + ordersStatus.getOrderNo()+" ordersStatus.getStatusCode() = "+ordersStatus.getStatusCode());
//				if (!ordersStatus.getStatusCode().equals("7")) { // (7, "已支付,已完成") 入库处理
//					log.error("userCard " + userCard
//							+ " Class:OmsBespeakServiceImpl -> method:ev3c0101Bespeak -> result:Exist not pay order!");
//					return false; // 存在未支付订单,直接返回
//				}
//			}
//		} catch (BizException e) {
//			log.error("allow charge although getOrdersStatus exception userCard " + userCard +" " + e.getMessage());
//			return true;// 查询异常了，返回真，还是允许预约或充电
//		}
//		return true;

	}

}
